<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>BEC Systems</title>
    <subtitle>I help small teams build connected products — capable teams that need to ship real hardware, and keep shipping. Consulting, open-source tools, and writing on platform thinking for embedded Linux and IoT.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://bec-systems.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://bec-systems.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-08-10T00:00:00+00:00</updated>
    <id>https://bec-systems.com/atom.xml</id>
    <entry xml:lang="en">
        <title>🧱 The hardest things</title>
        <published>2026-08-10T00:00:00+00:00</published>
        <updated>2026-08-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0346-the-hardest-things/"/>
        <id>https://bec-systems.com/blog/0346-the-hardest-things/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0346-the-hardest-things/">&lt;p&gt;The magic of product development appears to live in the complex things: the
clever circuit design, the brilliant algorithm, the integration of many
technologies. Observation suggests the opposite. Success is grounded in doing
the simple things well: discipline, communication, source control, release,
update, simple and extendable data structures, user feedback, conversations,
humility, consistency, documentation, transparency, tracking, automation. These simple
things form the framework that allows iteration on the hard, valuable ones. A
team of a few people can get by without doing the simple things well; anything beyond that becomes a challenge. None of them are beyond the reach of a reasonably competent human, yet they are often the hardest to do. Why?&lt;&#x2F;p&gt;
&lt;p&gt;The reasons are many: lack of discipline, laziness, busyness, self-importance.
But the biggest one may simply be a lack of awareness. What is missing is not
always apparent, and something more urgent always competes for attention. Seeing what is missing is often what we need help with.&lt;&#x2F;p&gt;
&lt;p&gt;Those who create space for the simple things end up with even more space, and with the infrastructure needed to work on the complex ones.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-hardest-things.png&quot; alt=&quot;The simple things are the foundation the complex work rests on&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧹 zephyr-snmp v0.1.0 - a huge cleanup!</title>
        <published>2026-08-05T00:00:00+00:00</published>
        <updated>2026-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0345-zephyr-snmp-v0-1-0-a-huge-cleanup/"/>
        <id>https://bec-systems.com/blog/0345-zephyr-snmp-v0-1-0-a-huge-cleanup/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0345-zephyr-snmp-v0-1-0-a-huge-cleanup/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-snmp&quot;&gt;zephyr-snmp&lt;&#x2F;a&gt; adds SNMP v1 and v2c
support to the Zephyr RTOS. It started as a port of the lwIP SNMP code, and
along the way I concluded it would be easier to maintain if it went fully
Zephyr-native: Zephyr code style, Zephyr APIs, etc. What is new in v0.1.0:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A complete
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-snmp&#x2F;tree&#x2F;main&#x2F;samples&#x2F;agent&quot;&gt;sample&lt;&#x2F;a&gt; to
start from&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-snmp&#x2F;blob&#x2F;main&#x2F;.github&#x2F;workflows&#x2F;build.yml&quot;&gt;CI in GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-snmp&#x2F;blob&#x2F;main&#x2F;.github&#x2F;workflows&#x2F;release.yml&quot;&gt;Release automation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Extensive documentation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Doing things the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;framework&#x2F;&quot;&gt;Release First&#x2F;Platform Thinking&lt;&#x2F;a&gt; way …&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;zephyr-snmp-v0-1-0-a-huge-cleanup.png&quot; alt=&quot;zephyr-snmp v0.1.0 cleanup&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚣 Rowing the race you need at the end</title>
        <published>2026-08-04T00:00:00+00:00</published>
        <updated>2026-08-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0344-rowing-the-race-you-need-at-the-end/"/>
        <id>https://bec-systems.com/blog/0344-rowing-the-race-you-need-at-the-end/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0344-rowing-the-race-you-need-at-the-end/">&lt;p&gt;Daniel James Brown’s &lt;em&gt;The Boys in the Boat&lt;&#x2F;em&gt; follows the University of Washington
eight-oar crew that won gold in Berlin in 1936. The part that stays with me is
how they rowed the middle of a race.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;husky-clipper.jpg&quot; alt=&quot;The Husky Clipper, the eight-oar shell George Pocock built for the University of Washington crew that won gold in Berlin in 1936, hanging in the Conibear Shellhouse in Seattle. Photo by AdmiralHts, CC BY-SA 4.0, via Wikimedia Commons.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Washington was a come-from-behind crew. Other boats tore off the line and took
an early lead. Washington took a clean start, settled to a lower stroke rate
than anyone else, and let the field go. What the crew was buying with those
middle thousand meters was swing, the state where all eight pull as one and the
boat lifts and seems to carry itself. Swing is where the speed actually comes
from, and a crew that blows itself out in the first minute never finds it.&lt;&#x2F;p&gt;
&lt;p&gt;George Pocock, the boat builder who made the Husky Clipper and served as the
crew’s quiet mentor, put what rowing teaches this way:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Harmony, balance, and rhythm. They’re the three things that stay with you
your whole life.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The pressure at the start of a project runs the other way. Get a demo up, show
motion, take the early lead. That first sprint always looks like speed, and an
early lead bought with skipped foundations is a rate no team can hold.&lt;&#x2F;p&gt;
&lt;p&gt;The middle of the project is where a team finds swing. Builds get fast, releases
become routine, the pieces fit together, and everyone can see how the whole
system works. That investment feels like lost ground while it is happening,
because the boat ahead is still ahead.&lt;&#x2F;p&gt;
&lt;p&gt;But the race is won at the finish, and in product development the finish is
long: the release, the update after it, the field bugs, the second product built
on the same foundation. That is what the reserve is for.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;release-first.com&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt; should not be confused with fast,
explosive starts. Release First starts small and unimpressive, and the focus is
on the smallest increment that is useful to others, not a big show.&lt;&#x2F;p&gt;
&lt;p&gt;This is where AI can deceive us. It can very quickly put together a very
impressive first demo with a very nice-looking UI: it looks … nearly done.
That time would probably have been better spent using AI to help write plans,
document architecture, research technologies, better understand user needs, etc.&lt;&#x2F;p&gt;
&lt;p&gt;The schedule asks how fast we can go. The more important question is what rate
we can hold for the whole race. A fast explosive start is impressive, but rarely
what matters in the end. And the only way to go fast for the long haul is to
invest in efficiency. What matters is each stroke along the way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛰️ Simple IoT now processes GPS data</title>
        <published>2026-08-03T00:00:00+00:00</published>
        <updated>2026-08-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0343-simple-iot-now-processes-gps-data/"/>
        <id>https://bec-systems.com/blog/0343-simple-iot-now-processes-gps-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0343-simple-iot-now-processes-gps-data/">&lt;p&gt;Simple IoT now processes GPS data. Three sources are supported:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Serial receiver speaking NMEA&lt;&#x2F;li&gt;
&lt;li&gt;gpsd daemon over TCP&lt;&#x2F;li&gt;
&lt;li&gt;Built-in simulator that generates realistic tracks with no hardware attached&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All three publish the same points — latitude, longitude, altitude, speed,
heading, fix quality, satellite count — so everything downstream stays the same
no matter which one is configured.&lt;&#x2F;p&gt;
&lt;p&gt;Pairing this with &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;victoriametrics.com&#x2F;&quot;&gt;VictoriaMetrics&lt;&#x2F;a&gt; for storage
and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;grafana.com&#x2F;&quot;&gt;Grafana&lt;&#x2F;a&gt; for viewing makes an excellent combination
for edge devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;siot-gps-dashboard.jpg&quot; alt=&quot;Grafana dashboard showing a simulated GPS track, position, speed, altitude, and fix quality&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;gpsd is an interesting project that I’ve never used before. From the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gpsd.gitlab.io&#x2F;gpsd&#x2F;&quot;&gt;gpsd web site&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPSD is everywhere in mobile embedded systems. It underlies the map service on
Android phones. It’s ubiquitous in drones, robot submarines, and driverless
cars. It’s increasingly common in recent generations of manned aircraft,
marine navigation systems, and military vehicles.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;See the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;user&#x2F;gps.html&quot;&gt;GPS documentation&lt;&#x2F;a&gt; for
configuration details.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧊 Why small teams have to be good at borrowing</title>
        <published>2026-07-30T00:00:00+00:00</published>
        <updated>2026-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0342-the-difference-between-large-and-small-teams/"/>
        <id>https://bec-systems.com/blog/0342-the-difference-between-large-and-small-teams/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0342-the-difference-between-large-and-small-teams/">&lt;p&gt;Large and small teams differ in many ways, but one difference stands out: how
much of the system gets built versus borrowed. Compared to large teams, small
teams must borrow a lot more than they build. If we use the iceberg analogy, a
lot more of the project is below the surface and somewhat hidden by default.&lt;&#x2F;p&gt;
&lt;p&gt;Which means a small team’s skill at borrowing sets how much time remains for the
part only that team can build.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;small-teams-borrow.png&quot; alt=&quot;Build above the waterline, borrow below it&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Exercise: Build vs Borrow</title>
        <published>2026-07-29T00:00:00+00:00</published>
        <updated>2026-07-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0341-exercise-build-vs-borrow/"/>
        <id>https://bec-systems.com/blog/0341-exercise-build-vs-borrow/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0341-exercise-build-vs-borrow/">&lt;p&gt;In the course of product development we &lt;strong&gt;build&lt;&#x2F;strong&gt; and we &lt;strong&gt;borrow&lt;&#x2F;strong&gt; components.
Some examples of each:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Build:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Write code (create software)&lt;&#x2F;li&gt;
&lt;li&gt;Design a PCB (printed circuit board)&lt;&#x2F;li&gt;
&lt;li&gt;Design a custom mechanical component&lt;&#x2F;li&gt;
&lt;li&gt;Create a custom test setup&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Borrow:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use an OSS (open-source software) library&lt;&#x2F;li&gt;
&lt;li&gt;Integrate a SOM (system on module) into a product&lt;&#x2F;li&gt;
&lt;li&gt;Use an off-the-shelf enclosure&lt;&#x2F;li&gt;
&lt;li&gt;Use existing tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Exercise: create a diagram with a horizontal line. On top of the line, list all
the items you are building. Below the line, list all the items you are
borrowing. Document why. Ask AI (Claude Code, etc.) to examine your project and
try to find any you have not thought of.&lt;&#x2F;p&gt;
&lt;p&gt;The benefit of this exercise is to help us visualize what we are dealing with.
Some insights that might result:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Have we drawn the line between building and borrowing correctly, or do we need
to adjust something?&lt;&#x2F;li&gt;
&lt;li&gt;Do we understand all the things we are borrowing? Should something be
replaced&#x2F;updated? Should we add&#x2F;remove something? Is something high risk?&lt;&#x2F;li&gt;
&lt;li&gt;With all components, what value are they providing? Are they moving us forward
or holding us back?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;exercise-build-vs-borrow.png&quot; alt=&quot;Build above the line, borrow below it&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 Do schedule estimates get more or less confident over time?</title>
        <published>2026-07-28T00:00:00+00:00</published>
        <updated>2026-07-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0340-do-schedule-estimates-get-more-or-less-confident-over-time/"/>
        <id>https://bec-systems.com/blog/0340-do-schedule-estimates-get-more-or-less-confident-over-time/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0340-do-schedule-estimates-get-more-or-less-confident-over-time/">&lt;p&gt;There are two trajectories for schedule confidence.&lt;&#x2F;p&gt;
&lt;p&gt;A schedule feels safest when it is nailed down up front, often built around what
management wants to hear. Detailed Gantt charts add to that feeling. The
modeling has value, but it rarely reflects reality in a complex system.
Developers shape their status reports to match the expected story, and problems
stay buried to fit the narrative handed down. Near the end of the project, the
unknowns finally reveal themselves and the delays arrive. The schedule ends up
less certain at the “end” of the project than at the beginning.&lt;&#x2F;p&gt;
&lt;p&gt;Another approach ships the first release as soon as possible, then the next. Each
release updates the end date based on what the last one taught. Confidence grows
over time because the unknowns and the problems surface early.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;schedule-confidence-over-time.png&quot; alt=&quot;Two schedule confidence trajectories over time&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚧 Gatekeepers are ineffective</title>
        <published>2026-07-27T00:00:00+00:00</published>
        <updated>2026-07-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0339-gatekeepers-are-ineffective/"/>
        <id>https://bec-systems.com/blog/0339-gatekeepers-are-ineffective/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0339-gatekeepers-are-ineffective/">&lt;p&gt;In the context of complex systems, gatekeepers are ineffective. In product
development, a gatekeeper is often a middle manager who relays information from
one person to another.&lt;&#x2F;p&gt;
&lt;p&gt;As an example, we have been struggling for the past year to get an installation
of a monitoring system doing what the customer wanted. The data was coming from
a PLC and was not in a usable format. I asked several times if the PLC program
could be modified, and was told no. Finally I asked if there happened to be any
more registers already in the PLC that contained the data we needed. There were,
and the solution was then simple. This process could have been drastically
shortened if I could have had direct communication with the PLC programmer early
on.&lt;&#x2F;p&gt;
&lt;p&gt;Gatekeepers are necessary at times to protect people doing work from needless
interruptions, or because of NDAs and security restrictions. But even in the
scenario of preventing interruptions, I’m not sure gatekeepers are the solution
rather than modifying the process. Perhaps all requests could be put into an
issue tracking system and then prioritized according to the business needs.
Processes like Scrum exist for this reason.&lt;&#x2F;p&gt;
&lt;p&gt;Any time we find ourselves relaying information (example: copying text from one
email to another email), we should ask ourselves: should I just connect these two
people and have them talk directly? If not, why not?&lt;&#x2F;p&gt;
&lt;p&gt;A gatekeeper tightly controls who can do their job, thus tends to do things in a
closed way.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;gatekeeper.png&quot; alt=&quot;A gatekeeper standing on a wall between customer and supplier, relaying every message&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Enablers do things in an open way that enables others to easily contribute. The
enabler mindset is not a free-for-all as there can still be reviews, checks, and
quality standards. But, there are no barriers to work and communication shifting to where it
is needed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;enabler.png&quot; alt=&quot;An enabler alongside a customer and supplier who talk directly and iterate with each other&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Are you a gatekeeper or an enabler?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✉️ Drafting emails in Markdown</title>
        <published>2026-07-24T00:00:00+00:00</published>
        <updated>2026-07-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0338-drafting-emails-in-markdown/"/>
        <id>https://bec-systems.com/blog/0338-drafting-emails-in-markdown/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0338-drafting-emails-in-markdown/">&lt;p&gt;As developers, we use Markdown all the time: in documentation, GitHub issues,
etc. Pretty much every tool supports it now, except email. With email, we are
still stuck with a 2005 MS Word experience.&lt;&#x2F;p&gt;
&lt;p&gt;Why Markdown? Once you know the simple syntax, composing Markdown is super fast.
It is much faster than finding and clicking on buttons in a rich text editor.
And the result is much more effective than simple text. Readers can scan the
message quickly by looking at headings, and information is formatted cleanly.
Formatted text is more effective communication.&lt;&#x2F;p&gt;
&lt;p&gt;I use Thunderbird, and the Markdown plugin I was using went unmaintained. So I
turned Claude onto making a new one. The result is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;thunderbird-markdown-compose&quot;&gt;Thunderbird Markdown Compose&lt;&#x2F;a&gt;.
This plugin has some nice features:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Simple, so easy to maintain&lt;&#x2F;li&gt;
&lt;li&gt;Converts pasted rich text to Markdown for easy editing&lt;&#x2F;li&gt;
&lt;li&gt;Can be quickly turned off&lt;&#x2F;li&gt;
&lt;li&gt;Provides a simple way to scale images&lt;&#x2F;li&gt;
&lt;li&gt;Mixes nicely with the previous message in replies&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;See the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;C7O-fzulo3o&quot;&gt;demo video&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛣️ The two ditches</title>
        <published>2026-07-23T00:00:00+00:00</published>
        <updated>2026-07-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0337-the-two-ditches/"/>
        <id>https://bec-systems.com/blog/0337-the-two-ditches/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0337-the-two-ditches/">&lt;p&gt;Along roads, there is often a ditch or some undesirable obstacle on either side
of the road you want to avoid. The same can be said for most of life, including
product development. There are two common errors:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Build it all yourself&lt;&#x2F;strong&gt;: You drown in plumbing, becoming a full-time maintainer
of what others maintain better. There are other variations of this such as
build everything entirely from source, etc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Rent the whole thing&lt;&#x2F;strong&gt;: You base your product on someone else’s platform and
lose the ability to own your destiny: can’t swap components, hostage to their
roadmap, pricing, and lifecycle.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The art of platform thinking is to optimize the path between these two extremes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-two-ditches.png&quot; alt=&quot;The two ditches: build it all yourself vs. rent the whole thing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Accelerating or Decelerating?</title>
        <published>2026-07-22T00:00:00+00:00</published>
        <updated>2026-07-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0336-accelerating-or-decelerating/"/>
        <id>https://bec-systems.com/blog/0336-accelerating-or-decelerating/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0336-accelerating-or-decelerating/">&lt;p&gt;Is your work accelerating or decelerating? This may be hard to measure, but in
our gut we know. A few ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Where do we spend our time? Moving things forward, or just keeping things
afloat?&lt;&#x2F;li&gt;
&lt;li&gt;Are we releasing more or less often?&lt;&#x2F;li&gt;
&lt;li&gt;How about the time from idea to deployment? Increasing or decreasing?&lt;&#x2F;li&gt;
&lt;li&gt;Are we more or less worried about deploying a change into production than last
week?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is the difference between scaling and stalling out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;accelerating-or-decelerating.png&quot; alt=&quot;Accelerating or decelerating&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧩 From PCB change to mechanical model in one script</title>
        <published>2026-07-21T00:00:00+00:00</published>
        <updated>2026-07-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0335-from-pcb-change-to-mechanical-model-in-one-script/"/>
        <id>https://bec-systems.com/blog/0335-from-pcb-change-to-mechanical-model-in-one-script/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0335-from-pcb-change-to-mechanical-model-in-one-script/">&lt;p&gt;One way to go faster is to automate the transfer of data between tools. We
recently created a script to update a PCB model in one step. Previously this
would take a few minutes to export the file from KiCad to a STEP model, and then
update the mechanical model from the STEP export. Once scripted, this takes a
few seconds.&lt;&#x2F;p&gt;
&lt;p&gt;This may not seem like a lot, but when the process is easy and fast, we’ll do it
more often, and likely end up with a better design with less wasted effort, as
we can visualize problems and opportunities for optimization earlier.&lt;&#x2F;p&gt;
&lt;p&gt;FreeCAD has progressed a lot in recent years, and with the addition of the
Assembly workbench in late 2024, FreeCAD is now a great tool for modeling these
types of products. Models for most off-the-shelf parts like enclosures are
readily available, so product modeling is mostly just assembling these
individual part models.&lt;&#x2F;p&gt;
&lt;p&gt;This also illustrates the power of open tools like KiCad and FreeCAD. Both use
open formats and have Python&#x2F;CLI interfaces, so they are easy to script. Claude
Code seems to know how to do all this, so you don’t have to be a Python expert.&lt;&#x2F;p&gt;
&lt;p&gt;Local + Open + AI = an efficient, integrated workflow.&lt;&#x2F;p&gt;
&lt;p&gt;See the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;i7StDopw0kI&quot;&gt;walkthrough video&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📥 Email is not a workflow</title>
        <published>2026-07-20T00:00:00+00:00</published>
        <updated>2026-07-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0334-email-is-not-a-workflow/"/>
        <id>https://bec-systems.com/blog/0334-email-is-not-a-workflow/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0334-email-is-not-a-workflow/">&lt;p&gt;A recent meeting surfaced a problem: BOM changes in the engineering systems were
not reliably reaching the production systems. “I told ’em” is how we had been
doing things. We told manufacturing about the changes and handed over links to
the updated release package, and items still fell through the cracks. Someone
asked: “can you automatically email the production people when there is a
release?” That helps, but only a little more than “I told ’em,” because &lt;strong&gt;email
is NOT a workflow&lt;&#x2F;strong&gt;. At best it is a notification. The problem is not notifying
people of things; it is tracking the work.&lt;&#x2F;p&gt;
&lt;p&gt;Workflows have many characteristics, but three stand out in this scenario:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Priority&lt;&#x2F;strong&gt;: Workflow items carry a clear priority. What matters, what is
moving now, and what comes next all sit in view.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Tracking&lt;&#x2F;strong&gt;: Current status, recent changes, discussions, and related
information live in one place.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transparency&lt;&#x2F;strong&gt;: Everyone involved sees the list and the status of any item.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Many things qualify as a workflow tool. The simplest starting point is a Kanban
board where cards move from left to right: Trello, or issues in
GitHub&#x2F;GitLab&#x2F;Gitea. Tools are plentiful and often free. The harder shift is
thinking in terms of workflows rather than meetings and messages.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;email-is-not-a-workflow.png&quot; alt=&quot;Email is not a workflow&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔌 GitPLM: An easy way to manage your KiCad library using CSV files in Git</title>
        <published>2026-07-15T00:00:00+00:00</published>
        <updated>2026-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0333-gitplm-an-easy-way-to-manage-your-kicad-library-using-csv-files-in-git/"/>
        <id>https://bec-systems.com/blog/0333-gitplm-an-easy-way-to-manage-your-kicad-library-using-csv-files-in-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0333-gitplm-an-easy-way-to-manage-your-kicad-library-using-csv-files-in-git/">&lt;p&gt;GitPLM now supports the KiCad HTTP Library API for an easy connection between
your part library and KiCad.&lt;&#x2F;p&gt;
&lt;p&gt;GitPLM manages product lifecycle information through a Git-based workflow. It
stores the parts database and BOMs in CSV files, so everything is version
controlled and works well for collaborative design.&lt;&#x2F;p&gt;
&lt;p&gt;With the KiCad HTTP Libraries feature, GitPLM can serve parts data directly to
KiCad. The server watches the partmaster directory and reloads the CSV files
when they change, so edits show up in KiCad without restarting the server.&lt;&#x2F;p&gt;
&lt;p&gt;See the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&#x2F;gitplm#-kicad-http-libraries-support&quot;&gt;KiCad HTTP Libraries support&lt;&#x2F;a&gt;
section in the README for the full details, and there is a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=n07GTHSm_SQ&quot;&gt;demo video&lt;&#x2F;a&gt; that walks through it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧊 Web application architecture</title>
        <published>2026-07-14T00:00:00+00:00</published>
        <updated>2026-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0332-web-application-architecture/"/>
        <id>https://bec-systems.com/blog/0332-web-application-architecture/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0332-web-application-architecture/">&lt;p&gt;In helping someone choose technology for a web application, we’ve had a lot of
discussions about various frameworks, languages, etc. AI tools will always push
you toward NodeJS&#x2F;JavaScript technologies. Yet, when you ask them for details,
they will often admit that Rails is probably a better technology for
workflow-heavy business apps.&lt;&#x2F;p&gt;
&lt;p&gt;The UI is the part you see: the part that is exciting, and the part React does
pretty well. The boring parts (authentication, migrations, modeling, security,
etc.) are parts you don’t see, but are also important and may determine whether
you have a sustainable product or a mess down the road.&lt;&#x2F;p&gt;
&lt;p&gt;There are good reasons to use various frameworks (real-time requirements, etc.),
but I think Rails is the standard for full-stack frameworks, especially for
small teams. You should at least discuss all the aspects in the graphic below
and have a plan for how you are going to solve them if using something else.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;web-application-architecture.jpeg&quot; alt=&quot;The Web App Iceberg&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Below is an AI-generated comparison, so it may not be completely accurate, but
it is a good starting point when evaluating web-application technology.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;&#x2F;th&gt;&lt;th&gt;Rails&lt;&#x2F;th&gt;&lt;th&gt;Meteor&lt;&#x2F;th&gt;&lt;th&gt;Phoenix&lt;&#x2F;th&gt;&lt;th&gt;AdonisJS&lt;&#x2F;th&gt;&lt;th&gt;Next.js&lt;&#x2F;th&gt;&lt;th&gt;NestJS&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;ORM&#x2F;Data Modeling&lt;&#x2F;td&gt;&lt;td&gt;✅ ActiveRecord&lt;&#x2F;td&gt;&lt;td&gt;⚠️ Collections&lt;&#x2F;td&gt;&lt;td&gt;✅ Ecto&lt;&#x2F;td&gt;&lt;td&gt;✅ Lucid&lt;&#x2F;td&gt;&lt;td&gt;❌ Bring your own&lt;&#x2F;td&gt;&lt;td&gt;⚠️ External&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Migrations&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️ Generators&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️ Libraries&#x2F;Auth.js&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Authorization&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;⚠️ Libraries&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️ Libraries&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Transactions&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;Depends&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Background Jobs&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;✅ Oban&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Real-time Updates&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅ LiveView&#x2F;PubSub&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;WebSockets&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Full Stack Framework&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️ Mostly UI&#x2F;API&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Convention over Configuration&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Batteries Included&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔩 Generating Mechanical Models with Claude Code</title>
        <published>2026-07-09T00:00:00+00:00</published>
        <updated>2026-07-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0331-open-tools-let-the-ai-in/"/>
        <id>https://bec-systems.com/blog/0331-open-tools-let-the-ai-in/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0331-open-tools-let-the-ai-in/">&lt;p&gt;We recently needed a mechanical model of a USB coupler. On a whim, I suggested
that the designer try using Claude Code to create it in FreeCAD from a 2D
drawing - it worked! No MCP or complex setup needed. (Although there is an MCP
available for FreeCAD).&lt;&#x2F;p&gt;
&lt;p&gt;We’ve been doing similar things with KiCad.&lt;&#x2F;p&gt;
&lt;p&gt;This illustrates the power of local workflows and open tools like FreeCad and
KiCad.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;freecad-usb-coupler.jpeg&quot; alt=&quot;A USB coupler model built in FreeCAD by Claude Code from a 2D drawing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🪑 The missing leg of reliability</title>
        <published>2026-04-22T00:00:00+00:00</published>
        <updated>2026-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0330-the-missing-leg-of-reliability/"/>
        <id>https://bec-systems.com/blog/0330-the-missing-leg-of-reliability/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0330-the-missing-leg-of-reliability/">&lt;p&gt;After a conversation with
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;tim-bird-453499&#x2F;&quot;&gt;Tim Bird&lt;&#x2F;a&gt; about
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elisa.tech&#x2F;space-grade-linux-sig&#x2F;&quot;&gt;Space-Grade Linux&lt;&#x2F;a&gt;, an idea about
reliability emerged. The obvious legs of reliable systems are design and
testing. What is less obvious is the third leg: &lt;strong&gt;active users&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Use, coupled with the ability to report issues or contribute changes, directly
correlates to reliability. Those of us
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;022&#x2F;&quot;&gt;running Arch Linux&lt;&#x2F;a&gt; fearlessly upgrade our systems,
and don’t worry that things are going to break with a new kernel version. While
Linux has strict design requirements and some testing, the biggest contributor
to its reliability is its
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;how-is-arch-linux-so-reliable&#x2F;1520&quot;&gt;large, active user base&lt;&#x2F;a&gt;.
By active, I mean someone who can report problems or contribute fixes. Microsoft
Windows has a large user base too, but users are insulated from developers and
it shows.&lt;&#x2F;p&gt;
&lt;p&gt;Just this week, I was collaborating with a user on a reporting feature and
uncovered a subtle bug in how daylight savings time was handled — the kind of
thing my own testing was never going to catch. As systems get more complex, this
kind of active use matters more, especially for small teams without chip-scale
verification resources. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;release-first.com&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt; is the
approach I’m trying with all &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&quot;&gt;my projects&lt;&#x2F;a&gt; to
eliminate the barrier between developers and users, and let use help drive
reliability.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;missing-leg-of-reliability.png&quot; alt=&quot;The three legs of reliability: Design, Testing, and Active Users&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💻 Why the terminal still matters</title>
        <published>2026-04-16T00:00:00+00:00</published>
        <updated>2026-04-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0329-why-the-terminal-still-matters/"/>
        <id>https://bec-systems.com/blog/0329-why-the-terminal-still-matters/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0329-why-the-terminal-still-matters/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;terminal-photo.png&quot; alt=&quot;terminal&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Starting in the 1970s, the terminal, popularized by Unix, has been a mainstay
in computing. Many developers today, and increasingly non-developers, are using
the terminal. In previous years the terminal was defined by a physical monitor
and keyboard displaying green text. Today, it is typically an application that
provides only a command prompt and text interface. Many developers still edit
code in terminal-based applications such as Vim or Helix. Why?&lt;&#x2F;p&gt;
&lt;p&gt;There are likely many reasons, but I think the most important one is that the
terminal is the most powerful computing environment ever invented.&lt;&#x2F;p&gt;
&lt;p&gt;“What!” you say, “Look at my iPad, that is the most powerful computer
interface ever. I’m not going back to DOS.”&lt;&#x2F;p&gt;
&lt;p&gt;Notice, I said “powerful,” not “nice.” Yes, an iPad is definitely nice to use,
but it is limited. You can only run the handful of apps you have installed, and
use them in prescribed ways. The terminal has hundreds (if not thousands) of commands
and applications preinstalled on every Linux system. You can compose commands
into scripts. There is no limit to what you can do.&lt;&#x2F;p&gt;
&lt;p&gt;The terminal is the AI-native platform. Agents are &lt;em&gt;very&lt;&#x2F;em&gt; good at running and
composing the hundreds of terminal commands. The terminal still matters, and with
AI, more than ever.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📧 How to solve the email problem?</title>
        <published>2026-04-14T00:00:00+00:00</published>
        <updated>2026-04-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0328-the-real-problem-with-email/"/>
        <id>https://bec-systems.com/blog/0328-the-real-problem-with-email/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0328-the-real-problem-with-email/">&lt;p&gt;How many hours go into just processing email? One reason it’s so consuming: when a message hits the inbox, it feels like it needs a response. It feels like real work.&lt;&#x2F;p&gt;
&lt;p&gt;There are several ways to handle the “too much email” problem:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ignore it.&lt;&#x2F;strong&gt; Read some email, and let the rest get buried.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Filter it.&lt;&#x2F;strong&gt; Route newsletters and other non-critical emails to folders.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Use new tools.&lt;&#x2F;strong&gt; Tools like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hey.com&#x2F;&quot;&gt;Hey&lt;&#x2F;a&gt; or Gmail’s automatic categorization help ensure only important emails reach the inbox.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Use other messaging tools.&lt;&#x2F;strong&gt; Signal, Discord, and Slack are now popular with teams. This may just shift the problem, but it’s also easier to skip things that aren’t relevant.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Solve the problem at the source.&lt;&#x2F;strong&gt; Shift more information to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0327-you-can-t-improve-an-email&#x2F;&quot;&gt;other mediums&lt;&#x2F;a&gt; that are more appropriate for long-lived information, or move conversations to where the work is happening (issues, PRs, team messaging).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;All of these help, but option #5 is worth a closer look — addressing the source of unnecessary email tends to be the most effective approach.&lt;&#x2F;p&gt;
&lt;p&gt;This is another example where I’ve found &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;release-first.com&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt; helps with problems like too much email. A Release First mindset tends to shift information handling away from transient messaging systems to permanent ones — where information is useful, long-lived, and versioned.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-real-problem-with-email.png&quot; alt=&quot;Solving the email problem at the source&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 You can&#x27;t improve an email</title>
        <published>2026-04-13T00:00:00+00:00</published>
        <updated>2026-04-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0327-you-can-t-improve-an-email/"/>
        <id>https://bec-systems.com/blog/0327-you-can-t-improve-an-email/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0327-you-can-t-improve-an-email/">&lt;p&gt;I’ve been moving discussions out of email and into versioned Markdown files.
Here’s what I’m noticing.&lt;&#x2F;p&gt;
&lt;p&gt;Email has a structural problem: the only options are reply and quote. The
original message can never be improved. When someone joins a project later, the
context is buried in a thread they weren’t on. And every reply adds to
everyone’s inbox backlog.&lt;&#x2F;p&gt;
&lt;p&gt;A Markdown file in a Git repo works differently. I updated a design doc last
week that I first wrote months ago — refined the language, added what we learned
since then. Anyone on the team can see and modify the current version. The repo
tracks every change.&lt;&#x2F;p&gt;
&lt;p&gt;There are certainly good uses for email and messaging. But I’m treating email as
ephemeral coordination now, and putting anything I want to last into something
anyone can revise.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;you-cant-improve-an-email.png&quot; alt=&quot;Email vs Versioned Doc&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ Tools or Processes?</title>
        <published>2026-04-07T00:00:00+00:00</published>
        <updated>2026-04-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0326-tools-or-processes/"/>
        <id>https://bec-systems.com/blog/0326-tools-or-processes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0326-tools-or-processes/">&lt;p&gt;What matters more – having better tools or better processes? One tends to
enable, the other to restrict. Companies often split into tool-builder cultures
(optimized for enabling engineers and teams) and process cultures (optimized for
control, repeatability, and compliance). Both can succeed, but for different
kinds of problems and at different scales.&lt;&#x2F;p&gt;
&lt;p&gt;With a good enough tool, the process becomes obvious. It represents the easiest
way to do something, so people naturally adopt it. But the tools need to be
really good. Nobody has to force people to use Google search, Perplexity, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Tools are bottom up, processes are top down.&lt;&#x2F;p&gt;
&lt;p&gt;Tools are easy to evolve and improve by anyone with the skills to build them.
Processes are often difficult to change, as that typically involves obtaining
permission.&lt;&#x2F;p&gt;
&lt;p&gt;Tools are tightly coupled with the work. Processes often become decoupled.&lt;&#x2F;p&gt;
&lt;p&gt;Especially with AI, the future belongs to people who can build tools, not those
entitled to mandate processes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tools-or-processes.png&quot; alt=&quot;Tools vs Processes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛩️ Why did the Wright Brothers succeed?</title>
        <published>2026-04-02T00:00:00+00:00</published>
        <updated>2026-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0325-why-did-the-wright-brothers-succeed/"/>
        <id>https://bec-systems.com/blog/0325-why-did-the-wright-brothers-succeed/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0325-why-did-the-wright-brothers-succeed/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;wright-brothers-first-flight.jpg&quot; alt=&quot;The Wright Brothers’ first powered flight, December 17, 1903, at Kitty Hawk, North Carolina. Photo by John T. Daniels. Public domain, via Wikimedia Commons.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While Samuel Langley had $100,000 (equivalent to $3.5 million today) in funding,
a team of engineers, and Washington connections, the Wrights were bicycle
mechanics from Dayton, Ohio with a fraction of those resources. Langley’s
approach was to design the perfect flying machine on paper, build it, and then
attempt a single dramatic launch. The Wrights took a fundamentally different
path.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;They did a lot of experiments.&lt;&#x2F;strong&gt; The Wrights built a wind tunnel and tested
over 200 wing shapes. They flew over a thousand glider flights at Kitty Hawk
before ever attaching an engine. Each flight was observable, measurable, and
informative. They were not trying to fly; they were trying to learn.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;They built the entire system, not just the exciting part.&lt;&#x2F;strong&gt; Langley focused on
the engine and aerodynamics — the glamorous engineering. The Wrights recognized
that control was the unsolved problem. They invented three-axis control (wing
warping, rudder, and elevator) and practiced it through hundreds of glider
flights. They built the ability to fly, land, adjust, and fly again — before
optimizing the product.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;They used short iteration cycles.&lt;&#x2F;strong&gt; Each season at Kitty Hawk was a learning
cycle. They would fly, observe, return to Dayton, analyze, redesign, and come
back. Problems surfaced early. When published lift tables turned out to be
wrong, they discovered it through testing, built their own wind tunnel, and
generated correct data. They didn’t wait until the final launch to find out
their assumptions were flawed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Langley’s failure was a Release Last failure.&lt;&#x2F;strong&gt; Langley tested his full-scale
Aerodrome exactly twice. Both times it crashed into the Potomac. With no
incremental learning, no progressive testing, and no feedback loop, two failed
launches ended the entire program. The gap between design and reality was never
closed because there was no mechanism to close it incrementally.&lt;&#x2F;p&gt;
&lt;p&gt;Why did the Wright brothers succeed with 100x less funding and far fewer
resources than Langley? They took a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;release-first.com&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt;
approach, with many small iterations. They developed prototypes that saw real
use — a process that surfaced reality early and often. They released. They
measured. They adjusted. And they flew. Langley went for the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0307-the-big-1-0-release&#x2F;&quot;&gt;Big Release&lt;&#x2F;a&gt; which
resulted in a BIG 1.0 humiliation.&lt;&#x2F;p&gt;
&lt;p&gt;Resources don’t always determine outcomes. The ability to release - to put
something real into the world, learn from it, and iterate - does.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 What has changed around edge build systems?</title>
        <published>2026-04-01T00:00:00+00:00</published>
        <updated>2026-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0324-what-has-changed-around-edge-build-systems/"/>
        <id>https://bec-systems.com/blog/0324-what-has-changed-around-edge-build-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0324-what-has-changed-around-edge-build-systems/">&lt;p&gt;Reflecting on Embedded Linux&#x2F;Edge build systems, several things have changed:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ARM and RISC-V hardware is fast.&lt;&#x2F;strong&gt; Modern ARM boards and cloud instances
(AWS Graviton, Hetzner CAX) build at speeds that make cross-compilation
unnecessary for most workloads. For development, QEMU user-mode emulation
can build ARM images on x86 without a cross-toolchain — slower, but correct
and simple.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Applications are moving to modern languages.&lt;&#x2F;strong&gt; Go, Rust, Zig, Python, and
Node.js have their own dependency management, package managers, and caching.
The elaborate cross-compilation and sysroot machinery in traditional build
systems targets C&#x2F;C++ and applies less to these modern languages. Build
systems that work with these packaging systems, rather than trying to replace
them, tend to gain more traction.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Docker changed how teams distribute tooling.&lt;&#x2F;strong&gt; Containers offer a simple
and efficient way to distribute build tooling, reducing the need to rebuild
the world.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AI changes the interface.&lt;&#x2F;strong&gt; Build systems are hard because there are
thousands of tedious details to sort through, dozens of different build
tools, and hundreds of different projects that all do things a little
differently. AI turns out to be quite good at sorting through all this, but
works best when build metadata is structured and queryable rather than buried
in shell scripts and environment variables.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is not the same world as 20, 10, or even 1 year ago. It may be time for a
new edge build system … stay tuned 🙂.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-has-changed-edge-build-systems.png&quot; alt=&quot;What has changed around edge build systems&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 Why Go Works Well for Building CLIs</title>
        <published>2026-03-30T00:00:00+00:00</published>
        <updated>2026-03-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0323-go-is-the-language-for-clis/"/>
        <id>https://bec-systems.com/blog/0323-go-is-the-language-for-clis/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0323-go-is-the-language-for-clis/">&lt;p&gt;The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0322-api-cli-skills-the-future-of-ai-agents&#x2F;&quot;&gt;last post&lt;&#x2F;a&gt;
discussed the importance of command line interfaces (CLIs) in the AI agent
stack. The next question is — what language works best for building CLIs?
Consider the requirements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Often a CLI needs to interact with APIs.&lt;&#x2F;li&gt;
&lt;li&gt;Easy to build and distribute to all platforms.&lt;&#x2F;li&gt;
&lt;li&gt;A terminal user interface (TUI) is a nice touch.&lt;&#x2F;li&gt;
&lt;li&gt;Reasonably fast. No one likes to wait for a CLI tool to start up.&lt;&#x2F;li&gt;
&lt;li&gt;Easy to develop.&lt;&#x2F;li&gt;
&lt;li&gt;Works well with AI.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Although many notable recent CLI tools use Rust, Go offers a pragmatic solution
for most teams.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Networking in Go is first class, so natural for APIs.&lt;&#x2F;li&gt;
&lt;li&gt;AI is good at writing Go.&lt;&#x2F;li&gt;
&lt;li&gt;Super easy to build for any platform.&lt;&#x2F;li&gt;
&lt;li&gt;Reliable enough for most use cases.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;charm.land&#x2F;&quot;&gt;Charm&lt;&#x2F;a&gt; packages make it easy to build a TUI.&lt;&#x2F;li&gt;
&lt;li&gt;Can distribute as a single binary (embedded runtime&#x2F;assets).&lt;&#x2F;li&gt;
&lt;li&gt;Go is an excellent modern runtime.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The speed and extra reliability of Rust or Zig may justify those languages in
some cases. However, development tends to be harder in those languages for most
tasks.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;go-notes&#x2F;319&quot;&gt;Go remains a pragmatic choice&lt;&#x2F;a&gt; for
getting things done.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;basecamp&#x2F;basecamp-cli&quot;&gt;DHH&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;steipete?tab=repositories&amp;amp;q=&amp;amp;type=&amp;amp;language=go&amp;amp;sort=&quot;&gt;Peter Steinberger&lt;&#x2F;a&gt;
seem to think so too …&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;go-is-the-language-for-clis.png&quot; alt=&quot;Go is the language for CLIs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔌 API + CLI + Skills = the Future of AI Agents</title>
        <published>2026-03-26T00:00:00+00:00</published>
        <updated>2026-03-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0322-api-cli-skills-the-future-of-ai-agents/"/>
        <id>https://bec-systems.com/blog/0322-api-cli-skills-the-future-of-ai-agents/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0322-api-cli-skills-the-future-of-ai-agents/">&lt;p&gt;DHH’s
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;basecamp-becomes-agent-accessible-3ae6b949&quot;&gt;recent post&lt;&#x2F;a&gt;
offers a glimpse into the future:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“So while we keep cooking on actually-useful native AI features
in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;basecamp.com&#x2F;&quot;&gt;Basecamp&lt;&#x2F;a&gt;,
we’re &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;basecamp.com&#x2F;agents&quot;&gt;launching a fully agent-accessible version today&lt;&#x2F;a&gt;.
We’ve &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;basecamp&#x2F;bc3-api&quot;&gt;revamped our API&lt;&#x2F;a&gt;,
created &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;basecamp&#x2F;basecamp-cli&quot;&gt;a brand-new CLI&lt;&#x2F;a&gt;, and
wrapped it all
in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;basecamp&#x2F;basecamp-cli&#x2F;blob&#x2F;main&#x2F;skills&#x2F;basecamp&#x2F;SKILL.md&quot;&gt;a skill&lt;&#x2F;a&gt; to
teach agents how best to use it all. It works remarkably well, and it’s really
fast too.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Especially check out the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;basecamp&#x2F;basecamp-cli&#x2F;blob&#x2F;main&#x2F;skills&#x2F;basecamp&#x2F;SKILL.md&quot;&gt;skill&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This matches what Peter Steinberger, the author of OpenClaw, has
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;openclaw-notes&#x2F;1664?u=cbrake&quot;&gt;been saying&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“You know, you know what I love? That half a year ago, like everyone was
talking about MCPs … and I was like, “Sc*** MCPs. &lt;strong&gt;Every MCP would be better&lt;&#x2F;strong&gt;
&lt;strong&gt;as a CLI.&lt;&#x2F;strong&gt;” And now this stuff doesn’t even have MCP support. I mean, it,
it has with asterisks, but not in the core lair, and nobody’s complaining.“&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Why do CLIs work so well?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;No MCP server needed.&lt;&#x2F;li&gt;
&lt;li&gt;Atomic process with an exit code and text stdout&#x2F;stderr — exactly the kind of
deterministic loop agents need for self-correction.&lt;&#x2F;li&gt;
&lt;li&gt;Compose naturally via pipes, redirection, and shell scripting.&lt;&#x2F;li&gt;
&lt;li&gt;Low integration overhead.&lt;&#x2F;li&gt;
&lt;li&gt;Deploy anywhere.&lt;&#x2F;li&gt;
&lt;li&gt;An agent can figure out how to use a CLI by running &lt;code&gt;&amp;lt;cli command&amp;gt; --help&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;CLIs mix API calls with local operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With an existing CLI, creating a Claude skill for it is straightforward.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;api-cli-skills-future-ai-agents.png&quot; alt=&quot;API + CLI + Skills = AI Agent&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>❓ Better questions get better answers</title>
        <published>2026-03-25T00:00:00+00:00</published>
        <updated>2026-03-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0321-avoid-leading-questions/"/>
        <id>https://bec-systems.com/blog/0321-avoid-leading-questions/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0321-avoid-leading-questions/">&lt;p&gt;A common challenge in communication is getting people to open up and share what
they really think. One way to improve this is to avoid leading questions, which
steer a person toward a particular answer instead of letting them respond freely.
Some examples:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Leading question&lt;&#x2F;th&gt;&lt;th&gt;Open-ended alternative&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;“What do you think about SAP?”&lt;&#x2F;td&gt;&lt;td&gt;“Can you walk me through how you currently manage your core business processes (finance, operations, etc.)?”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;“Have you ever thought of having a PMO?”&lt;&#x2F;td&gt;&lt;td&gt;“How do you currently organize and oversee your projects and initiatives?”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;“Have you ever thought of a web site?”&lt;&#x2F;td&gt;&lt;td&gt;“How do customers typically find information about your company and its services today?”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;“Why don’t you use Git?”&lt;&#x2F;td&gt;&lt;td&gt;“How do you currently track changes and collaborate on code?”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;“Why aren’t you Release First?”&lt;&#x2F;td&gt;&lt;td&gt;“Can you describe your current process for making work available for others to use?”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The key is to start with the problem we are solving instead of our preconceived
solution. So … what is your process for making work available for others to
use?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;avoid-leading-questions.png&quot; alt=&quot;Better questions get better answers&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏞️ Communicating Status Without Demanding Attention</title>
        <published>2026-03-24T00:00:00+00:00</published>
        <updated>2026-03-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0320-overcommunicating/"/>
        <id>https://bec-systems.com/blog/0320-overcommunicating/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0320-overcommunicating/">&lt;p&gt;One precept of
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0319-how-to-manage-up&#x2F;&quot;&gt;“managing up”&lt;&#x2F;a&gt; is that
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;newsletter.weskao.com&#x2F;i&#x2F;138205680&#x2F;9-over-communication-might-be-the-right-amount&quot;&gt;over-communicating&lt;&#x2F;a&gt;
tends to work better than under-communicating. This is where releasing “often”
comes in. Releases offer a natural way to communicate status because they don’t
feel like something requiring a response, the way a direct email or message does.
Releases done right are like a peaceful mountain stream flowing by — something
people can observe and dip their hand into when there is something they are
interested in. The stream does not demand attention, but provides a comforting
presence that things are getting done — continuously, reliably, and peacefully.
To carry the analogy a little further, consider the stagnant pond of obscurity
where nobody is quite sure what is going on. Or the torrential flood of bugs and
customer problems.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;communicating-status.png&quot; alt=&quot;Communicating status like a mountain stream&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 How to manage up</title>
        <published>2026-03-20T00:00:00+00:00</published>
        <updated>2026-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0319-how-to-manage-up/"/>
        <id>https://bec-systems.com/blog/0319-how-to-manage-up/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0319-how-to-manage-up/">&lt;p&gt;The concept of
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;newsletter.weskao.com&#x2F;p&#x2F;15-principles-for-managing-up&quot;&gt;“managing up”&lt;&#x2F;a&gt;
can be a valuable practice for developers and middle managers. It seems
counter-intuitive that we need to manage the people over us. But, simply put,
managing up is intentionally improving the relationship with your boss to make
their job easier, align with their priorities, and improve the outcomes for both
of you. This is not manipulation, kissing up, or trying to look good, but rather
communication and understanding.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;release-first.com&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt; is a useful tool for managing up. It
gives those above us clear visibility into what we are doing in a language they
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0318-the-release-is-a-language-everyone-undestands&#x2F;&quot;&gt;can understand&lt;&#x2F;a&gt;,
and even allows them to use and try it in many cases. Release First does not
replace all the interpersonal skills needed to manage up, but it does establish
the groundwork so you can focus on the important parts of relationships.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;how-to-manage-up.png&quot; alt=&quot;How to manage up&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 The release is a language everyone understands</title>
        <published>2026-03-19T00:00:00+00:00</published>
        <updated>2026-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0318-the-release-is-a-language-everyone-undestands/"/>
        <id>https://bec-systems.com/blog/0318-the-release-is-a-language-everyone-undestands/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0318-the-release-is-a-language-everyone-undestands/">&lt;p&gt;A release is a good way for developers to communicate with everyone else:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What got done&lt;&#x2F;li&gt;
&lt;li&gt;What changed&lt;&#x2F;li&gt;
&lt;li&gt;How to use or build the latest version&lt;&#x2F;li&gt;
&lt;li&gt;Where to get support or provide feedback&lt;&#x2F;li&gt;
&lt;li&gt;A regular cadence for communication&lt;&#x2F;li&gt;
&lt;li&gt;A standard format everyone can follow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Releases can save a lot of time normally spent in status meetings and generating
status reports, freeing up developers and managers to focus on the work that
needs to get done.&lt;&#x2F;p&gt;
&lt;p&gt;And with AI, releases are easier than ever to generate and automate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;release-is-a-language.png&quot; alt=&quot;The release is a language everyone understands&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📦 What is a release used for?</title>
        <published>2026-03-18T00:00:00+00:00</published>
        <updated>2026-03-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0317-what-is-a-release-used-for/"/>
        <id>https://bec-systems.com/blog/0317-what-is-a-release-used-for/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0317-what-is-a-release-used-for/">&lt;p&gt;A release needs to happen before a product is shipped to customers for sale. Across the spectrum of the product development
lifecycle, releases are used for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Generate feedback (so we know where we stand)&lt;&#x2F;li&gt;
&lt;li&gt;Provide something others can build on (this is how we scale)&lt;&#x2F;li&gt;
&lt;li&gt;Deliver value to customers (this is how revenue is generated)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Feedback, scaling, and profit - the engines of business.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-is-a-release-used-for.png&quot; alt=&quot;what is a release used for&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚡ The essence of shipping faster</title>
        <published>2026-03-17T00:00:00+00:00</published>
        <updated>2026-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0316-the-essence-of-shipping-faster/"/>
        <id>https://bec-systems.com/blog/0316-the-essence-of-shipping-faster/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0316-the-essence-of-shipping-faster/">&lt;p&gt;In recent conversations about why development schedules slip and what to do
about it, several themes continue to come up:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Openness&lt;&#x2F;strong&gt; - This is key to surfacing issues early.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Safety&lt;&#x2F;strong&gt; - People must feel safe being transparent and speaking up.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Collaboration&lt;&#x2F;strong&gt; - People must be willing to share, help others, and receive
help from others or use what others have built. Effective people don’t work in
silos.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These all come down to culture.  As one person put it:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Process without culture doesn’t work.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0302-the-human-factors&#x2F;&quot;&gt;human factors&lt;&#x2F;a&gt; are
the hard part, and the most difficult for technically oriented people to figure
out. But, they are the key to high-performing teams.&lt;&#x2F;p&gt;
&lt;p&gt;Great leadership and how to affect culture is beyond the scope of this article,
but Release First is a powerful tool for assisting leaders in developing a
healthy culture. Why? Because releasing early and often is the ultimate act of
transparency. It provides visibility into exactly what the team accomplishes and
how well they accomplish it. Issues surface early. There are
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0296-the-illusion-of-project-meta-data&#x2F;&quot;&gt;no proxies&lt;&#x2F;a&gt;
to hide behind.&lt;&#x2F;p&gt;
&lt;p&gt;Releasing also gives people confidence and satisfaction as they see things
moving forward. The job of a leader is to encourage people to release their
work, encourage others to use those releases, and foster a culture of speaking
up. The focus must remain on the path forward to the next release, not on
blaming people for what went wrong in the last release. Do this, and the rest
will largely take care of itself.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;essence-of-shipping-faster.png&quot; alt=&quot;The essence of shipping faster&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔀 What is the difference between MVP and Release First?</title>
        <published>2026-03-13T00:00:00+00:00</published>
        <updated>2026-03-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0315-what-is-the-difference-between-mvp-and-release-first/"/>
        <id>https://bec-systems.com/blog/0315-what-is-the-difference-between-mvp-and-release-first/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0315-what-is-the-difference-between-mvp-and-release-first/">&lt;p&gt;MVP (Minimum Viable Product) is a concept from Eric Ries’
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;book-review-the-lean-startup&#x2F;275&quot;&gt;Lean Startup&lt;&#x2F;a&gt;
methodology. The idea is to build the smallest possible version of a product
that lets you test a hypothesis with real users. Instead of spending months
building a full-featured product, you strip it down to the core value
proposition, ship it, and learn from actual usage whether you’re solving a real
problem. If the hypothesis is wrong, you pivot early before investing heavily.
MVP is fundamentally about product&#x2F;market fit — are we building the right thing?&lt;&#x2F;p&gt;
&lt;p&gt;MVP and Release First share DNA but differ in focus.&lt;&#x2F;p&gt;
&lt;p&gt;Release First asks a different question: can we ship with confidence, early and
often? It focuses on building the release infrastructure (CI&#x2F;CD, tests,
automation, versioning, update mechanisms) before the product itself. It applies
broadly — not just software, but hardware, documentation, and any engineering
artifact.&lt;&#x2F;p&gt;
&lt;p&gt;The risks they address are different too. MVP addresses the risk of building
something nobody wants. Release First addresses the risk of the last 10% taking
90% of the time — the integration nightmares, the untested release processes,
the meta-data illusion where project tracking says you’re on track while reality
diverges.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;MVP&lt;&#x2F;th&gt;&lt;th&gt;Release First&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Core question&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Are we building the right thing?&lt;&#x2F;td&gt;&lt;td&gt;Can we ship with confidence, early and often?&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Focus&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Scope reduction — cut features to learn faster&lt;&#x2F;td&gt;&lt;td&gt;Process — build the Big Green Button first&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Applies to&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Product&#x2F;market fit validation&lt;&#x2F;td&gt;&lt;td&gt;All engineering artifacts (SW, HW, docs, PCBs)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Risk addressed&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Building something nobody wants&lt;&#x2F;td&gt;&lt;td&gt;The last 10% takes 90% of the time&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;When it ends&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Once the hypothesis is validated&#x2F;invalidated&lt;&#x2F;td&gt;&lt;td&gt;Never — it’s an ongoing discipline&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;They’re complementary. An MVP without release infrastructure still risks blowing
up at the end. And Release First without scope discipline can still build the
wrong thing. The ideal is both — a small scope (MVP thinking) delivered through
a repeatable, automated release process (Release First thinking) - efficiently,
quickly, and confidently - over and over …&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;mvp-vs-release-first.png&quot; alt=&quot;MVP vs Release First&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✅ Each release is 100% done</title>
        <published>2026-03-12T00:00:00+00:00</published>
        <updated>2026-03-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0314-each-release-is-100-done/"/>
        <id>https://bec-systems.com/blog/0314-each-release-is-100-done/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0314-each-release-is-100-done/">&lt;p&gt;One common problem in product development is developers not finishing a feature
or task. They get it to 70% done and rush off to the next thing. Bugs linger,
edge cases go unhandled, testing falls short, and the release process remains
incomplete. “100% done” does not mean the product is 100% done — it means each
release is complete, tested, and high quality. Quality products emerge from many
small high-quality steps, not from a pile of slop that somehow gets polished by
QA at the end of the development cycle.&lt;&#x2F;p&gt;
&lt;p&gt;Release First is a simple way to ensure each step in the journey is 100% done
and high quality.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;each-release-is-100-done.png&quot; alt=&quot;Each release is 100% done&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💡 A Simple Example</title>
        <published>2026-03-11T00:00:00+00:00</published>
        <updated>2026-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0313-a-simple-example/"/>
        <id>https://bec-systems.com/blog/0313-a-simple-example/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0313-a-simple-example/">&lt;p&gt;The Release First mindset starts with how you handle reasonably complex
information (a procedure, technical details, etc). There are two approaches:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Email or message the information.&lt;&#x2F;li&gt;
&lt;li&gt;Put it in Git and send a link or PR.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first is transient, inaccessible, and difficult to build on or improve.&lt;&#x2F;p&gt;
&lt;p&gt;The second is permanent, reusable, accessible, and something people can build on.
It is an asset.&lt;&#x2F;p&gt;
&lt;p&gt;Sure, there are times when email or messaging is the appropriate forum for
discussions. But the minute there is something of value, turn that into a
permanent, team-accessible asset. This is how teams build value.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;a-simple-example.png&quot; alt=&quot;A Simple Example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏷️ The simple approach to versioning</title>
        <published>2026-03-10T00:00:00+00:00</published>
        <updated>2026-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0312-the-simple-approach-to-versioning/"/>
        <id>https://bec-systems.com/blog/0312-the-simple-approach-to-versioning/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0312-the-simple-approach-to-versioning/">&lt;p&gt;The biggest barrier to starting something is an unwillingness to start simple.
Let’s use versioning as an example. The natural tendency is to think that all
software components need their own version, which can be a daunting task to
implement, track, and manage. However, until a team is large enough to have
multiple groups dedicated to different tasks, instead put everything in a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;monoliths-and-monorepos&#x2F;202&quot;&gt;monorepo&lt;&#x2F;a&gt; and use a
single version for everything. Not every component needs to be released with
every version, only the ones that have changed. There are several advantages:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There is a single changelog to review.&lt;&#x2F;li&gt;
&lt;li&gt;It is easy to coordinate things - components of the same version should work
well together.&lt;&#x2F;li&gt;
&lt;li&gt;Much easier to use AI to execute tasks that involve multiple components. If
there are several repos, you are always fighting security checks when crossing
repos (at least in Claude Code).&lt;&#x2F;li&gt;
&lt;li&gt;It is easy and simple.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;“But!!!,” you say, “The versions won’t always be sequential, some will be
skipped for various components!!!” Why does this matter? If it bothers you,
release every component for every version. Automation can easily do this.&lt;&#x2F;p&gt;
&lt;p&gt;The resulting changelog looks something like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;2026-03-06 v3.0.18

[Server]

- Fix mongo iterator stopping on decode errors instead of skipping bad documents
  Add bson truncate tags to all int fields to handle float64 values from
  JavaScript

[GW]

- Improve response of Modbus polling.

[Portal]

- Add UI for e2e test status.

2026-03-06 v3.0.17

[Server]

- Log rule count each processing cycle to aid debugging

2026-03-06 v3.0.16

[E2E testing]

- Improved ntfy error messages to include response body for easier debugging.
- Reduced log noise: only log pump and cycle mirror state changes instead of
  continuous tank level.
- Added logging of test status on initial check and state changes.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start simple, and add complexity when there is a need.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;simple-approach-to-versioning.png&quot; alt=&quot;Simple approach to versioning&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📦 The bare minimum to call something a release</title>
        <published>2026-03-09T00:00:00+00:00</published>
        <updated>2026-03-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0311-the-bare-minimum-to-call-something-a-release/"/>
        <id>https://bec-systems.com/blog/0311-the-bare-minimum-to-call-something-a-release/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0311-the-bare-minimum-to-call-something-a-release/">&lt;p&gt;What is the bare minimum to call something a release? Consider the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;version&lt;&#x2F;a&gt; that increments with every release.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0114-who-is-a-changelog-for&#x2F;&quot;&gt;changelog&lt;&#x2F;a&gt;
that describes what has changed for every version and why it matters.&lt;&#x2F;li&gt;
&lt;li&gt;A clear identification of any assets
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&#x2F;parts&#x2F;blob&#x2F;main&#x2F;partnumbers.md&quot;&gt;IPNs&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Unique IDs for anything built
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;2563&#x2F;human-friendly-industrial-device-ids&#x2F;&quot;&gt;HFIDs&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;A place to store stuff where all this gets tracked over time
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0214-git-solves-the-problem-of-managing-files&#x2F;&quot;&gt;Git&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The concrete benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Exact knowledge of what exists.&lt;&#x2F;li&gt;
&lt;li&gt;Clear record of who did what when.&lt;&#x2F;li&gt;
&lt;li&gt;Clear communication to everyone involved.&lt;&#x2F;li&gt;
&lt;li&gt;Nothing gets lost.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Doing the above for all design assets (including documentation) from &lt;strong&gt;day one&lt;&#x2F;strong&gt;
in the development process improves thinking, communication, and
effectiveness — and reduces untold confusion and wasted time.&lt;&#x2F;p&gt;
&lt;p&gt;This does not need to be hard. Simple text files, spreadsheets, and CSV files
work great. It is perfectly fine to start small.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;bare-minimum-release.png&quot; alt=&quot;Bare minimum release&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>❓ Release Questions</title>
        <published>2026-03-06T00:00:00+00:00</published>
        <updated>2026-03-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0310-release-questions/"/>
        <id>https://bec-systems.com/blog/0310-release-questions/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0310-release-questions/">&lt;p&gt;Some questions to consider about a release:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;When is it created?&lt;&#x2F;li&gt;
&lt;li&gt;Where is it stored?&lt;&#x2F;li&gt;
&lt;li&gt;What does it contain?&lt;&#x2F;li&gt;
&lt;li&gt;How is it created?&lt;&#x2F;li&gt;
&lt;li&gt;Who uses it?&lt;&#x2F;li&gt;
&lt;li&gt;Why is it used?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;English_interrogative_words&quot;&gt;“Wh- questions”&lt;&#x2F;a&gt;
are a powerful technique for analyzing anything we do.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;release-questions.png&quot; alt=&quot;Release Questions&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤔 Two types of unknowns</title>
        <published>2026-03-05T00:00:00+00:00</published>
        <updated>2026-03-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0309-two-types-of-uknowns/"/>
        <id>https://bec-systems.com/blog/0309-two-types-of-uknowns/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0309-two-types-of-uknowns/">&lt;p&gt;There are two types of unknowns:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Things we don’t know.&lt;&#x2F;li&gt;
&lt;li&gt;Things we think are true, but are not. &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Both can inflict havoc on our plans, but the second is the most damaging. Why?
The first is more associated with doing nothing. Bugs not known to be there,
etc. But the second prompts people to take action and go down a path that can be
difficult to undo (promised ship dates, features, etc.). It is not too hard to
say “oops, I did not know about that problem - we’ll fix it.” But it is really
hard to say “sorry, I was completely wrong about that.” - this takes a great
deal of humility.&lt;&#x2F;p&gt;
&lt;p&gt;While avoiding #1 is important, avoiding #2 is critical, because that forces
people to retrace their steps and admit they were wrong. While humbling oneself
is beneficial for character development, practically, it is difficult (if not
impossible) for most people to do, especially those in leadership positions. So
let’s
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0301-what-is-release-first&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt;, and
learn where we are wrong in little ways, rather than have a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0307-the-big-1-0-release&#x2F;&quot;&gt;BIG 1.0&lt;&#x2F;a&gt; humiliation.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;“It ain’t what you don’t know that gets you into trouble. It’s what you know
for sure that just ain’t so.” - Mark Twain (maybe)&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;two-types-of-unknowns.png&quot; alt=&quot;Two types of unknowns&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧊 The hardest thing to manage</title>
        <published>2026-03-04T00:00:00+00:00</published>
        <updated>2026-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0308-the-hardest-thing-to-manage/"/>
        <id>https://bec-systems.com/blog/0308-the-hardest-thing-to-manage/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0308-the-hardest-thing-to-manage/">&lt;p&gt;The things we know and understand are easy to manage. We can hire managers who
are good at this. Tools can effectively track this. Life is good. The difficulty
arises in the unknown. The iceberg analogy illustrates this well. The things we
see, understand, and touch are above water. Everything else is underwater. This
is often where unexpected problems arise. As systems get more complex, the size
of the unknown grows. We can’t predict what will happen in the unknown; the only
thing we can do is release and integrate early.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;iceberg.png&quot; alt=&quot;The hardest thing to manage&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎉 The BIG 1.0 Release</title>
        <published>2026-03-03T00:00:00+00:00</published>
        <updated>2026-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0307-the-big-1-0-release/"/>
        <id>https://bec-systems.com/blog/0307-the-big-1-0-release/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0307-the-big-1-0-release/">&lt;p&gt;BIG releases are appealing — the magical moment when everything comes together.
The months or years of hard work that finally come to fruition. The excitement
and fanfare of the BIG announcement. The accolades and admiration of customers
and the press.&lt;&#x2F;p&gt;
&lt;p&gt;… except, it
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0305-symptoms-of-not-releasing-first&#x2F;&quot;&gt;rarely works this way&lt;&#x2F;a&gt;
unless you are Apple or Tesla. And what we don’t see with high-end consumer
products is the rigorous internal release and testing programs … something
lower-volume industrial products don’t have the luxury and resources to do.&lt;&#x2F;p&gt;
&lt;p&gt;The BIG Release mindset assumes all the code and designs will magically ship
when the BIG day comes. It never goes this smoothly. Sure, we may build
prototypes and do testing, but unless we do these with release processes we can
reuse, it is hard to be confident we can do it again quickly, easily, and
accurately. One-off prototype processes don’t scale. Only release processes
scale. And the reality is that the rigor of releases in the prototype phase
works better anyway.&lt;&#x2F;p&gt;
&lt;p&gt;The solution is of course … Release First. The problem is that The BIG 1.0
Release fits human nature better (procrastination, excitement, and glory).
Release First is boring, tedious at first, and no one cares. The effort is
invisible and rarely gets rewarded. Very few developers are wired for Release
First. Thus, Release First is not a technical problem, but rather a cultural
one.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-big-1-0-release.png&quot; alt=&quot;The BIG Release vs Release First&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>❓ What is the difference between &quot;releasing&quot; and &quot;shipping&quot;?</title>
        <published>2026-03-02T00:00:00+00:00</published>
        <updated>2026-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0306-what-is-the-difference-between-releasing-and-shipping/"/>
        <id>https://bec-systems.com/blog/0306-what-is-the-difference-between-releasing-and-shipping/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0306-what-is-the-difference-between-releasing-and-shipping/">&lt;p&gt;Someone asked: “What is the difference between &lt;strong&gt;releasing&lt;&#x2F;strong&gt; and &lt;strong&gt;shipping&lt;&#x2F;strong&gt;?”
Are they the same thing?&lt;&#x2F;p&gt;
&lt;p&gt;In one sense they are. However, drawing a distinction here—though somewhat
arbitrary—is helpful in this context.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Release:&lt;&#x2F;strong&gt; Make something available.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Ship:&lt;&#x2F;strong&gt; Deliver to the customer for sale.&lt;&#x2F;p&gt;
&lt;p&gt;Releasing is part of the process to get something to the point where it provides
enough value that customers will pay for it. Releasing is the way useful work
gets shared with others and the delivery process gets refined. Releasing enables
early feedback needed to know exactly what to build. The Release is the way
different disciplines communicate around what the team is building. Releases are
a concrete measure of development progress. Releases build confidence in the
product.&lt;&#x2F;p&gt;
&lt;p&gt;The problem arises when the two are considered equivalent—when there is no
release until ship. Then inevitable surprises pile up.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;releasing-vs-shipping.png&quot; alt=&quot;Releasing vs Shipping&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚨 Problems with not Releasing First</title>
        <published>2026-02-27T00:00:00+00:00</published>
        <updated>2026-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0305-symptoms-of-not-releasing-first/"/>
        <id>https://bec-systems.com/blog/0305-symptoms-of-not-releasing-first/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0305-symptoms-of-not-releasing-first/">&lt;p&gt;What is the downside of not
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0301-what-is-release-first&#x2F;&quot;&gt;Releasing First&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Integration problems&lt;&#x2F;li&gt;
&lt;li&gt;Manufacturing issues&lt;&#x2F;li&gt;
&lt;li&gt;Last minute bugs appearing&lt;&#x2F;li&gt;
&lt;li&gt;Lack of product fit (does not solve customer’s problem)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The common theme is unforeseen problems that typically surface late in the
development cycle. The point of Release First is to expose unknowns early, when
there is still time to address them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;symptoms-not-releasing-first.png&quot; alt=&quot;Symptoms of not releasing first&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌅 Why optimizing the user release experience early is so important</title>
        <published>2026-02-25T00:00:00+00:00</published>
        <updated>2026-02-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0304-why-optimizing-the-user-release-experience-early-is-so-important/"/>
        <id>https://bec-systems.com/blog/0304-why-optimizing-the-user-release-experience-early-is-so-important/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0304-why-optimizing-the-user-release-experience-early-is-so-important/">&lt;p&gt;With Release First, the goal is to optimize the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0303-the-big-blue-button&#x2F;&quot;&gt;Big Blue Button&lt;&#x2F;a&gt; (make
it easy for users to use a release) early. Why is this important? There are many
reasons, but the most important is so that users actually use the release and
provide needed feedback early.&lt;&#x2F;p&gt;
&lt;p&gt;Without optimizing the release experience early (when the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0298-the-release-circle&#x2F;&quot;&gt;circle&lt;&#x2F;a&gt; is small),
developers soon become inundated with support issues as the circle grows.
Pretty soon the developers are doing nothing but support. Optimizing the user
experience early enables scaling.&lt;&#x2F;p&gt;
&lt;p&gt;Fix things early, when the stakes are low, not after the BIG 1.0 Release.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;optimizing-release-experience-early.png&quot; alt=&quot;Optimize Early vs Late&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔵 The Big Blue Button</title>
        <published>2026-02-24T00:00:00+00:00</published>
        <updated>2026-02-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0303-the-big-blue-button/"/>
        <id>https://bec-systems.com/blog/0303-the-big-blue-button/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0303-the-big-blue-button/">&lt;p&gt;In the past days, we’ve been focusing on the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0299-the-big-green-button&#x2F;&quot;&gt;Big Green Button&lt;&#x2F;a&gt;,
but there is another side of this - what happens after the release? Does the
release get used? If not, why not? If a release does not get used, there is
little point in releasing.&lt;&#x2F;p&gt;
&lt;p&gt;There are several aspects to consider in the usability of a release:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Communicating to users that a release is available and relevant to them.&lt;&#x2F;li&gt;
&lt;li&gt;Making it easy to consume the release.&lt;&#x2F;li&gt;
&lt;li&gt;An efficient way to support and get feedback from users.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We have a Big Green Button to create a release, so let’s continue the analogy
with a Big Blue Button that makes it easy for a user to consume a release. We
can’t just throw something over the wall (that may be technically very good and
complete) and expect magic to happen without any consideration for the user.
What does the Big Blue Button include?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clear documentation, tutorials, videos.&lt;&#x2F;li&gt;
&lt;li&gt;Well organized assets that are consistent from release to release.&lt;&#x2F;li&gt;
&lt;li&gt;An easy way to obtain&#x2F;install&#x2F;update the release.&lt;&#x2F;li&gt;
&lt;li&gt;Built-in help functionality, diagnostics, automated error reporting.&lt;&#x2F;li&gt;
&lt;li&gt;A community where the user feels included, supported, and part of something
bigger than themselves. This is important to have, even early on when the
internal team is the only user base.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One of the key warning flags is when a bunch of hand-holding and personalized
help is required for someone to use a release. Can manufacturing take what the
team produced and run with it? Can someone use a software service without
personalized support? Can someone set up and configure a product without a dozen
support calls? The point is not to avoid talking to users, but rather to talk to
them after they have used the product and can add value to the development
process.&lt;&#x2F;p&gt;
&lt;p&gt;There needs to be a symmetry between the Big Green Button and the Big Blue
Button - easy to produce and easy to consume, otherwise the flow will stall.
These are the factors that will differentiate developers and products in the AI
age.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-big-blue-button.png&quot; alt=&quot;Big Green Button to Big Blue Button flow with feedback loop&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧠 The Human Factors</title>
        <published>2026-02-23T00:00:00+00:00</published>
        <updated>2026-02-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0302-the-human-factors/"/>
        <id>https://bec-systems.com/blog/0302-the-human-factors/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0302-the-human-factors/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;gerald-weinberg&#x2F;1657&quot;&gt;Gerald M. Weinberg&lt;&#x2F;a&gt; once
said:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;No matter what the problem is, it’s always a people problem. — Gerald M.
Weinberg&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At its heart, release-first addresses the human element:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Our propensity to procrastinate in getting releases out.&lt;&#x2F;li&gt;
&lt;li&gt;Our fear that something might be broken in the release.&lt;&#x2F;li&gt;
&lt;li&gt;Our tendency to think short-term instead of long-term.&lt;&#x2F;li&gt;
&lt;li&gt;Our tendency to rush on to the next feature before finishing the one we
started.&lt;&#x2F;li&gt;
&lt;li&gt;Our tendency to skip tests when writing code.&lt;&#x2F;li&gt;
&lt;li&gt;Our OCD in needing to perfect something before anyone else can see it.&lt;&#x2F;li&gt;
&lt;li&gt;And the list goes on &lt;em&gt;ad infinitum&lt;&#x2F;em&gt; …&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Release-first at its core is a way to address human weaknesses. It is a simple
tweak in our behavior that anyone can do. It is a language that everyone can
understand. It can be measured by anyone without fancy tools. It is so absurdly
simple that most people will write it off as “obvious” or “too simple” and
instead reach to the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;merchants-of-complexity-4851301b&quot;&gt;merchants of complexity&lt;&#x2F;a&gt;.
But true effectiveness comes when we reduce things to the simplest form
possible, and remove all the accidental complexity.&lt;&#x2F;p&gt;
&lt;p&gt;So the next time you’re struggling with a release process, a testing gap, or a
feature that never quite ships — remember Weinberg. The problem isn’t the tools,
the framework, or the process. It’s us. Release-first works because it doesn’t
try to engineer around human nature — it simply makes the right behavior the
default behavior.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-human-factors.png&quot; alt=&quot;The Human Factors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>☝️ What do we mean by &quot;First&quot;?</title>
        <published>2026-02-20T00:00:00+00:00</published>
        <updated>2026-02-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0301-what-is-release-first/"/>
        <id>https://bec-systems.com/blog/0301-what-is-release-first/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0301-what-is-release-first/">&lt;p&gt;What do we mean by Release “First”? Several things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;First in the &lt;strong&gt;timeline&lt;&#x2F;strong&gt; of development.&lt;&#x2F;li&gt;
&lt;li&gt;First thing we &lt;strong&gt;focus&lt;&#x2F;strong&gt; on during implementation.&lt;&#x2F;li&gt;
&lt;li&gt;First &lt;strong&gt;priority&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Simply put, implement the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0299-the-big-green-button&#x2F;&quot;&gt;Big Green Button&lt;&#x2F;a&gt;
before implementing the actual deliverable. This might include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Tests&lt;&#x2F;li&gt;
&lt;li&gt;CI&#x2F;CD&lt;&#x2F;li&gt;
&lt;li&gt;Build automation&lt;&#x2F;li&gt;
&lt;li&gt;Deployment scripts&lt;&#x2F;li&gt;
&lt;li&gt;PCB release automation&lt;&#x2F;li&gt;
&lt;li&gt;Clear user documentation&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This becomes part of the review process, part of the culture, part of the
expectation, and part of the daily habit — make it easy to release.&lt;&#x2F;p&gt;
&lt;p&gt;Because the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0299-the-big-green-button&#x2F;&quot;&gt;Big Green Button&lt;&#x2F;a&gt;
does not ship to customers, forgetting and neglecting this step comes naturally.
Release First is a simple hack to ensure it gets done before the rush to do
other things.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-is-release-first.png&quot; alt=&quot;Release First: release infrastructure before the deliverable&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🟢 What is in the Big Green Button?</title>
        <published>2026-02-18T00:00:00+00:00</published>
        <updated>2026-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0300-what-is-in-the-big-green-button/"/>
        <id>https://bec-systems.com/blog/0300-what-is-in-the-big-green-button/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0300-what-is-in-the-big-green-button/">&lt;p&gt;As previously stated, the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0299-the-big-green-button&#x2F;&quot;&gt;Big Green Button&lt;&#x2F;a&gt;
enables teams to quickly and confidently release. But what is the Big Green
Button? Several things come to mind:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Automation that translates code&#x2F;design&#x2F;docs&#x2F;models into assets others can use.&lt;&#x2F;li&gt;
&lt;li&gt;Automated testing that builds confidence in the release.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These save developers time by avoiding repetitive, tedious tasks, avoiding
mistakes, and reducing support load. These investments have a very quick
payback.&lt;&#x2F;p&gt;
&lt;p&gt;The point with the Big Green Button analogy is that once we have a Big Green
Button, we don’t think about what is inside the button every time we release,
our minds are free to focus on other things.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-is-in-the-big-green-button.png&quot; alt=&quot;What is in the Big Green Button&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🟢 The Big Green Button</title>
        <published>2026-02-17T00:00:00+00:00</published>
        <updated>2026-02-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0299-the-big-green-button/"/>
        <id>https://bec-systems.com/blog/0299-the-big-green-button/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0299-the-big-green-button/">&lt;p&gt;The word “release” can be a noun (what gets released) or a verb (the process of
producing a release). “What” and “How”.&lt;&#x2F;p&gt;
&lt;p&gt;Many teams produce complete high-quality releases that allow them to produce or
deploy something at some point in time. However, each new release requires
significant manual effort:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Manually testing software to make sure it is solid.&lt;&#x2F;li&gt;
&lt;li&gt;Manually going through the process of generating output formats, and updating
drawings for manufacturing. This might involve double-checking the output
files.&lt;&#x2F;li&gt;
&lt;li&gt;Manually updating BOMs and top level information.&lt;&#x2F;li&gt;
&lt;li&gt;Manually updating instructions, manuals, and other released documentation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;An alternative to the above is the “Big Green Button” - a single step that can
convert designs&#x2F;code&#x2F;models&#x2F;documentation into something others (manufacturing,
sales, customers, stakeholders, etc.) can use. This is the critical point - do
you have a “Big Green Button”? Without one, releases naturally get delayed until
the last minute — losing opportunities for critical early feedback and the
ability to quickly response to new issues or needs.&lt;&#x2F;p&gt;
&lt;p&gt;The Big Green Button is what gets the work from developers to users - quickly
and confidently. And this is something &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;&quot;&gt;BEC&lt;&#x2F;a&gt; can help
with.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-big-green-button.png&quot; alt=&quot;The Big Green Button&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 The release circle</title>
        <published>2026-02-16T00:00:00+00:00</published>
        <updated>2026-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0298-the-release-circle/"/>
        <id>https://bec-systems.com/blog/0298-the-release-circle/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0298-the-release-circle/">&lt;p&gt;As previously discussed, a release is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;useful and quality&lt;&#x2F;a&gt;.
What counts as a release? One way to think about this is to view the release as
a circle with two attributes:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;What (it contains)&lt;&#x2F;li&gt;
&lt;li&gt;Who (it’s for)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Initially, there is not much in the circle (perhaps only a specification), and
only the development team and a few others in the organization are interested.
But it is something that can be used and built upon. The team will change and
expand it, but it will continue to exist in some form in all future releases.
This might start with a spec, then a UI prototype in the cloud, then a device
prototype based on a single-board-computer, then a custom system-on-module PCB,
and so on. As time goes on, the functionality expands and improves.&lt;&#x2F;p&gt;
&lt;p&gt;The circle of who uses a release also expands over time, to include sales and
marketing, management, beta-customers, and finally a general product release.
Over time, the number of customers also grows to include more varied use cases.&lt;&#x2F;p&gt;
&lt;p&gt;The key point is to release a small slice of &lt;em&gt;permanent&lt;&#x2F;em&gt; functionality early,
and then continue to grow&#x2F;add slices and the number of people who use the
product &lt;em&gt;during the product development cycle&lt;&#x2F;em&gt;. Waiting until the BIG Release is
too late. It’s OK to start small. As long as it’s
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;a release&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But there are things that are not a release:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Emails&lt;&#x2F;li&gt;
&lt;li&gt;Messages&lt;&#x2F;li&gt;
&lt;li&gt;Meetings&lt;&#x2F;li&gt;
&lt;li&gt;Memos&lt;&#x2F;li&gt;
&lt;li&gt;Experiments&lt;&#x2F;li&gt;
&lt;li&gt;Prototypes (that are not released)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Why? Because this information is not permanent. While others consume it and find
it very useful, it is transitory and cannot be continually used, refined, and
improved over time. It is one-off communication.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-release-circle.png&quot; alt=&quot;The Release Circle&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧩 Why things fall apart at the end</title>
        <published>2026-02-11T00:00:00+00:00</published>
        <updated>2026-02-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0297-why-things-fall-apart-at-the-end/"/>
        <id>https://bec-systems.com/blog/0297-why-things-fall-apart-at-the-end/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0297-why-things-fall-apart-at-the-end/">&lt;p&gt;As discussed in the previous two posts, things often go haywire near the end of
a project cycle, right before the BIG Release. Why is this? Things seem to go so
well at the beginning of the project. While it is impossible to detail every
reason this happens, a few are listed below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Technical debt&lt;&#x2F;strong&gt; occurs when problems are half-solved. Things appear to work,
but edge cases and inadequate testing lurk beneath the surface. As time
progresses, the system becomes more fragile, and significant amounts of time go
toward fighting bugs and unplanned problems.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Scope creep&lt;&#x2F;strong&gt; is a common phenomenon where features continually accumulate
throughout the project. Some of this is natural if it’s based on user feedback
and learning while implementing. However, there is an unnatural scope creep
rooted in engineering whims, just-in-case thinking, and a developer’s natural
propensity toward complexity. Just because something can be done does not mean
it should be.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Integration issues&lt;&#x2F;strong&gt; occur when one piece of work combines with another. This
is often when new edge cases surface.&lt;&#x2F;p&gt;
&lt;p&gt;Not correctly anticipating &lt;strong&gt;user needs&lt;&#x2F;strong&gt; is another problem. A team may build
something thinking the requirements are understood, but it is not until people
start using it that the real needs emerge.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, there are &lt;strong&gt;unknowns&lt;&#x2F;strong&gt; that simply cannot be anticipated. Complex
systems are just that — impossible to completely understand. People involved at
every level are fallible and unpredictable. A large amount of uncertainty simply
cannot be known or predicted up front.&lt;&#x2F;p&gt;
&lt;p&gt;The simplest way to address all of these issues is to move the end closer to the
beginning — Release First.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;why-things-fall-apart-at-the-end.png&quot; alt=&quot;Why things fall apart at the end&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🪞 The illusion of project meta-data</title>
        <published>2026-02-10T00:00:00+00:00</published>
        <updated>2026-02-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0296-the-illusion-of-project-meta-data/"/>
        <id>https://bec-systems.com/blog/0296-the-illusion-of-project-meta-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0296-the-illusion-of-project-meta-data/">&lt;p&gt;Many tools exist for managing and tracking projects: Jira, Trello, GitHub
projects&#x2F;issues, Notion, Airtable, Asana, MS Project, etc. These all can be very
useful. Why then does effective project tracking remain so elusive? As mentioned
in the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0295-what-is-the-1-problem-in-product-development&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt;,
in a typical scenario, things appear to progress well. Issues get checked off.
The burn-down chart tracks the line. But out of nowhere, monsters (bugs,
unanticipated feature requests, and integration problems) appear that catch
everyone off guard.&lt;&#x2F;p&gt;
&lt;p&gt;Several factors contribute to this problem. Foremost, the meta-data is exactly
that — “meta.” It is data about something; it is not the thing. There is no
guarantee it is complete and accurate. If the focus stays on the meta-data, the
meta-data will (perhaps unknowingly) be gamed to look good. If developers get
rewarded for checking issues off every sprint, they will eventually make sure
that happens, even though quality, maintainability, and other factors suffer.&lt;&#x2F;p&gt;
&lt;p&gt;I love tools, and use them every chance I get. I write
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;brun&quot;&gt;new tools&lt;&#x2F;a&gt; to solve problems. Tools are what
amplify our efforts. But tools in themselves don’t seem to be the answer. How
can we ensure our meta-data is accurate and not missing things? How can we know
our tools are not lying to us?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;the-illusion-of-project-meta-data.png&quot; alt=&quot;The illusion of project meta-data&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚢 What is the #1 problem in product development?</title>
        <published>2026-02-09T00:00:00+00:00</published>
        <updated>2026-02-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0295-what-is-the-1-problem-in-product-development/"/>
        <id>https://bec-systems.com/blog/0295-what-is-the-1-problem-in-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0295-what-is-the-1-problem-in-product-development/">&lt;p&gt;I’ll go first … a very common challenge is shipping on time and the resulting
uncertainty to the business. We often add a 2-3x factor on any estimates, but
sometimes even that is not enough.&lt;&#x2F;p&gt;
&lt;p&gt;Shipping (delivering value) is the bottom line — it generates revenue and
sustains the business. Delivering new products on time and providing subsequent
updates are critical. Without shipping, there is no value delivery. Often
businesses collaborate with customers throughout the development process. When
things are late, customers and partners lose confidence. Development team morale
tanks. It’s a downward spiral.&lt;&#x2F;p&gt;
&lt;p&gt;This problem has an even more painful manifestation — finding out just before the
BIG Release date that things are not coming together. As the saying goes, the
last 10% takes 90% of the time.
Surprises like this are devastating to everyone involved. Why do things fall
apart near the “end” of a project? Why don’t these issues surface sooner? These
are complex and perplexing problems, but worth exploring in the coming days.
Thoughts on this are always welcome.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;number-1-problem-product-dev.png&quot; alt=&quot;The #1 Problem in Product Development&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📦 More definitions of a release</title>
        <published>2026-02-04T00:00:00+00:00</published>
        <updated>2026-02-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0294-more-definitions-of-a-release/"/>
        <id>https://bec-systems.com/blog/0294-more-definitions-of-a-release/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0294-more-definitions-of-a-release/">&lt;p&gt;A release must be: &lt;em&gt;reliable, useful, repeatable, and predictable&lt;&#x2F;em&gt;. This
delivers outcomes of: &lt;em&gt;quality, value, timeliness, and consistency&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The second group is the outcome we want, the first group is what we focus on to
get there.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;release-definitions.png&quot; alt=&quot;Release definitions: focus on reliable, useful, repeatable, predictable to achieve quality, value, timeliness, and consistency&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ Do things that don&#x27;t scale</title>
        <published>2026-02-03T00:00:00+00:00</published>
        <updated>2026-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0293-do-things-that-don-t-scale/"/>
        <id>https://bec-systems.com/blog/0293-do-things-that-don-t-scale/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0293-do-things-that-don-t-scale/">&lt;p&gt;From Paul Graham’s popular essay
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;paulgraham.com&#x2F;ds.html&quot;&gt;Do Things That Don’t Scale&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Over-engaging with early users is not just a permissible technique for getting
growth rolling. For most successful startups it’s a necessary part of the
feedback loop that makes the product good. Making a better mousetrap is not an
atomic operation. Even if you start the way most successful startups have, by
building something you yourself need, the first thing you build is never quite
right. And except in domains with big penalties for making mistakes, it’s
often better not to aim for perfection initially. In software, especially, it
usually works best to get something in front of users as soon as it has a
quantum of utility, and then see what they do with it. Perfectionism is often
an excuse for procrastination, and in any case your initial model of users is
always inaccurate, even if you’re one of
them. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;paulgraham.com&#x2F;ds.html#f7n&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The feedback you get from engaging directly with your earliest users will be
the best you ever get. When you’re so big you have to resort to focus groups,
you’ll wish you could go over to your users’ homes and offices and watch them
use your stuff like you did when there were only a handful of them.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I should mention one sort of initial tactic that usually doesn’t work: &lt;strong&gt;the
Big Launch&lt;&#x2F;strong&gt;. I occasionally meet founders who seem to believe startups are
projectiles rather than powered aircraft, and that they’ll make it big if and
only if they’re launched with sufficient initial velocity. They want to launch
simultaneously in 8 different publications, with embargoes. And on a Tuesday,
of course, since they read somewhere that’s the optimum day to launch
something.&lt;&#x2F;p&gt;
&lt;p&gt;It’s easy to see how little launches matter. Think of some successful
startups. How many of their launches do you remember? All you need from a
launch is some initial core of users. How well you’re doing a few months later
will depend more on how happy you made those users than how many there were of
them. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;paulgraham.com&#x2F;ds.html#f10n&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So why do founders think launches matter? A combination of solipsism and
laziness. They think what they’re building is so great that everyone who hears
about it will immediately sign up. Plus it would be so much less work if you
could get users merely by broadcasting your existence, rather than recruiting
them one at a time. But even if what you’re building really is great, getting
users will always be a gradual process — partly because great things are
usually also novel, but mainly because users have other things to think about.&lt;&#x2F;p&gt;
&lt;p&gt;Partnerships too usually don’t work. They don’t work for startups in general,
but they especially don’t work as a way to get growth started. It’s a common
mistake among inexperienced founders to believe that a partnership with a big
company will be their big break. Six months later they’re all saying the same
thing: that was way more work than we expected, and we ended up getting
practically nothing out of it. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;paulgraham.com&#x2F;ds.html#f11n&quot;&gt;11&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It’s not enough just to do something extraordinary initially. You have to make
an extraordinary &lt;em&gt;effort&lt;&#x2F;em&gt; initially. Any strategy that omits the effort —
whether it’s expecting a big launch to get you users, or a big partner — is
ipso facto suspect.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;What Paul is talking about here is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt; — the
extremely tedious, manual effort required to get usable stuff in front of real
users. There is no substitute.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;do-things-that-dont-scale.png&quot; alt=&quot;Do things that don’t scale&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔮 Can we predict product development schedules?</title>
        <published>2026-02-02T00:00:00+00:00</published>
        <updated>2026-02-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0292-can-we-predict-product-development-schedules/"/>
        <id>https://bec-systems.com/blog/0292-can-we-predict-product-development-schedules/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0292-can-we-predict-product-development-schedules/">&lt;p&gt;Estimating or predicting product development is difficult. Teams often end up
adding a 2-3x padding to any estimate, because bitter experience has taught them
not to depend on their own estimates.&lt;&#x2F;p&gt;
&lt;p&gt;There will always be a high degree of variability in product development,
especially software development. Product development involves doing something
new. Teams discover exactly what they are building along the way. No one can
completely plan it up front.&lt;&#x2F;p&gt;
&lt;p&gt;However, we can do better. What is most damaging is not that a product is six
months late, rather it is that we did not figure this out until shortly before
the original anticipated release date.&lt;&#x2F;p&gt;
&lt;p&gt;Release First is a simple solution. By the time the planned release date comes
around, you have released dozens if not hundreds of releases. Some releases may
be documents, some may be hardware, and others software. But there have been
many opportunities for others to use something and provide feedback.
Additionally, you have had lots of practice releasing so there are no surprises.
We may have learned that it will take an extra 6 months to finish the product,
but we learned that early and the business has had time to adjust. Or we may
have gained so much efficiency through automation, and reduced wasted effort to
a level that we come out ahead of schedule (what we really want).&lt;&#x2F;p&gt;
&lt;p&gt;Release First eliminates surprises, and that is what matters in business.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;predict-schedules.png&quot; alt=&quot;Traditional vs Release First approach to product development schedules&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 How to make releases painless</title>
        <published>2026-01-29T00:00:00+00:00</published>
        <updated>2026-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0291-how-to-make-releases-painless/"/>
        <id>https://bec-systems.com/blog/0291-how-to-make-releases-painless/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0291-how-to-make-releases-painless/">&lt;p&gt;In the olden days, releases were a lot of work. The process involved manually
building&#x2F;testing, uploading to a distribution location, sending out
notifications to interested parties, etc. Supporting multiple platforms meant
even more work.&lt;&#x2F;p&gt;
&lt;p&gt;Today, there are better ways. With modern CI&#x2F;CD workflows, pushing a tag to a
repo triggers GitHub Actions to handle the rest.&lt;&#x2F;p&gt;
&lt;p&gt;As an example, in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;brun&quot;&gt;BRun&lt;&#x2F;a&gt; project, there are
several key pieces:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;brun&#x2F;blob&#x2F;main&#x2F;.github&#x2F;workflows&#x2F;ci.yml&quot;&gt;Tests&lt;&#x2F;a&gt; run
on every PR commit to ensure nothing breaks.&lt;&#x2F;li&gt;
&lt;li&gt;Go makes it
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;how-to-build-a-go-app-for-othe-u_Mc7qLUTGy8bWASnzm5YA#0&quot;&gt;super easy&lt;&#x2F;a&gt;
to build for other platforms. Anyone who has cross-compiled C&#x2F;C++ knows the
pain.&lt;&#x2F;li&gt;
&lt;li&gt;The amazing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;goreleaser.com&#x2F;&quot;&gt;GoReleaser&lt;&#x2F;a&gt; tool takes care of building
the release binaries and uploading them to GitHub.&lt;&#x2F;li&gt;
&lt;li&gt;A
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;brun&#x2F;blob&#x2F;main&#x2F;scripts&#x2F;extract-changelog.sh&quot;&gt;script&lt;&#x2F;a&gt;
automatically extracts the Changelog for the release that gets added to the
Release.&lt;&#x2F;li&gt;
&lt;li&gt;A GitHub action runs GoReleaser whenever the repo is tagged with ‘v*’.&lt;&#x2F;li&gt;
&lt;li&gt;GitHub sends notifications to watchers of the project. (Consider watching the
BRun project!)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The result is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;brun&#x2F;releases&quot;&gt;beautiful releases&lt;&#x2F;a&gt; for
every platform (Windows, MacOS, Linux, ARM, x86, RISC-V) created whenever
anything is improved, no matter how small. There is no friction to creating a
release.&lt;&#x2F;p&gt;
&lt;p&gt;Part of making all this happen is choosing the right technology. When it comes
to release and deployment, Go makes things really easy (compared to C++, Python,
Ruby, Java, etc.). There are trade-offs so make sure release is factored into
technology decisions. One way to ensure this happens is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0277-shipping-faster-leads-to-predictability&#x2F;&quot;&gt;do it first&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;painless-releases.png&quot; alt=&quot;Painless releases diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📖 When should you write the user manual?</title>
        <published>2026-01-27T00:00:00+00:00</published>
        <updated>2026-01-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0290-when-should-you-write-the-user-manual/"/>
        <id>https://bec-systems.com/blog/0290-when-should-you-write-the-user-manual/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0290-when-should-you-write-the-user-manual/">&lt;p&gt;Most of the time, teams write the user manual at the end of a product
development cycle right before the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0251-the-big-release-vs-a-continuous-flow-of-value&#x2F;&quot;&gt;Big 1.0 Release&lt;&#x2F;a&gt;.
It is one of those things that is not much fun, and teams subconsciously put it
off while fighting bigger fires. But what would happen if we write the user
manual first - even before the product spec? Some things that might happen:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We might think a little more from the user’s perspective during the
development.&lt;&#x2F;li&gt;
&lt;li&gt;Our upfront thinking would improve through the process of writing.&lt;&#x2F;li&gt;
&lt;li&gt;Internal&#x2F;beta releases would have documentation, allowing others to use them
without a lot of hand-holding (saving developers time).&lt;&#x2F;li&gt;
&lt;li&gt;We would get feedback on the user manual early in the development process so
it could be improved before release.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Good user documentation is part of a good release - it helps make the release
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;useful&lt;&#x2F;a&gt;. With
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmpdir-org&#x2F;tmpdir-claude-code-marketplace&#x2F;blob&#x2F;main&#x2F;doc-driven-development&#x2F;README.md&quot;&gt;doc-driven development&lt;&#x2F;a&gt;,
I typically start at the repository
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;README&quot;&gt;README.md&lt;&#x2F;a&gt; or other documentation close
to the code, but why not start with the user manual and derive more from that.
Start with the experience you want the user to have. Reverse the process.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;user-manual-timing.png&quot; alt=&quot;User manual timing comparison&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎬 Is a Demo the same as a Release?</title>
        <published>2026-01-26T00:00:00+00:00</published>
        <updated>2026-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0289-is-a-demo-the-same-as-a-release/"/>
        <id>https://bec-systems.com/blog/0289-is-a-demo-the-same-as-a-release/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0289-is-a-demo-the-same-as-a-release/">&lt;p&gt;Some development teams have a weekly demo where they might show what they are
working on to others in the company or the customer, which is a great idea as it
encourages hitting milestones and early feedback. However, is the “demo” just
another name for an “internal release?”&lt;&#x2F;p&gt;
&lt;p&gt;The “release” and “demo” mindsets have some differences. For a demo, quality or
automation may not be a priority. Engineers may record a video or present the
demo. Again, all of these are great ideas and should be done, but they are not a
release.&lt;&#x2F;p&gt;
&lt;p&gt;The key thing about a release is that someone else, other than the developers,
uses it. And the developers are confident enough to let other people use it.
This difference seems small on the surface, but is huge underneath. A release
comes with an expectation that drives automation and quality. The demo can
become a crutch that allows teams to avoid the hard work of delivering something
others can use. The mindset matters.&lt;&#x2F;p&gt;
&lt;p&gt;Again, the first internal release need not be feature complete and polished, but
whatever slice of functionality the team delivers should be usable by others
without a lot of props and hand-holding. Beware of proxies for delivering real
value: demos, closing tickets, milestones, etc. While these are all useful
tools, they are not an end in themselves. Measure value, not proxies.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;demo-vs-release.png&quot; alt=&quot;Demo vs Release&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⏱️ How do you find time for higher value tasks?</title>
        <published>2026-01-23T00:00:00+00:00</published>
        <updated>2026-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0288-how-do-you-find-time-for-higher-value-tasks/"/>
        <id>https://bec-systems.com/blog/0288-how-do-you-find-time-for-higher-value-tasks/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0288-how-do-you-find-time-for-higher-value-tasks/">&lt;p&gt;Do you (and by extension your organization) find yourself mired in minutia and
struggling to find time for higher value tasks? What is the solution?&lt;&#x2F;p&gt;
&lt;p&gt;You can hire more people to do the lower-value stuff (a perfectly valid
approach). You can also own
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0018-what-is-a-platform-v2&#x2F;&quot;&gt;YOUR Platform&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;One of the goals of
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0277-shipping-faster-leads-to-predictability&#x2F;&quot;&gt;Release First&lt;&#x2F;a&gt;&#x2F;Platform
Thinking is to shift time from low-value tasks (tedious repetitive work) to
high-value tasks (creative, innovative work).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;higher-value-tasks.png&quot; alt=&quot;Platform Thinking shifts time from tedious work to creative work&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Reliability tradeoffs</title>
        <published>2026-01-22T00:00:00+00:00</published>
        <updated>2026-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0287-reliability-tradeoffs/"/>
        <id>https://bec-systems.com/blog/0287-reliability-tradeoffs/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0287-reliability-tradeoffs/">&lt;p&gt;Recently, one of our servers running Arch Linux refused to boot after updates.
The fix was to comment out a line in the &lt;code&gt;&#x2F;etc&#x2F;default&#x2F;grub&lt;&#x2F;code&gt; file. It took
about 15 minutes to find and everything was done in a rescue terminal — no need
to boot from a rescue image. This server has been running for several
years, been updated hundreds of times, and this is the only time it would not boot.&lt;&#x2F;p&gt;
&lt;p&gt;Many dismiss Arch as a server OS because there is supposedly a higher likelihood
of things like the above happening. But in practice, they rarely happen and are
fairly quick to fix. So on one side of the equation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Easy to administer OS, latest software, no OS upgrades, etc. This saves a ton
of time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On the other side:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Occasional effort to fix an issue like the above.&lt;&#x2F;li&gt;
&lt;li&gt;Downtime while doing the above.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For a high-profile eCommerce site, downtime would matter, but for a small
business, 30 minutes of downtime makes no practical difference. The time saved
running Arch greatly swamps (by an order of magnitude or two) the time spent
fixing things that break. Admin time is many times more valuable than server
up-time. Even spending half a day rebuilding the site from scratch (which is
mostly automated) would not matter.&lt;&#x2F;p&gt;
&lt;p&gt;There is no one-size-fits-all. Just because Summit Federal Bank runs Crucible
Linux Enterprise edition does not mean everyone else needs to. Always consider
the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0163-the-entire-story&#x2F;&quot;&gt;benefit-cost ratio (BCR)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;reliability-tradeoffs.png&quot; alt=&quot;Reliability tradeoffs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Reliability, Cost, and Value</title>
        <published>2026-01-19T00:00:00+00:00</published>
        <updated>2026-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0286-reliability-cost-and-value/"/>
        <id>https://bec-systems.com/blog/0286-reliability-cost-and-value/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0286-reliability-cost-and-value/">&lt;p&gt;Everything has a cost and value to the customer. How much value does the
customer put on 99.999% reliability vs the value of other features they need? If
one system out of a thousand fails every 3 years (0.033% failure rate per year),
what does that cost compared to a set of features that allows the customer to
reduce operating costs 10%, or improve their general yearly reliability by 1%?&lt;&#x2F;p&gt;
&lt;p&gt;Certainly, safety-critical systems where human lives are involved are impossible
to quantify with simple equations. But when considering operational equipment
involving machines, understanding the real concerns of the customer and
delivering the most value becomes paramount.
Reliability&#x2F;security&#x2F;performance&#x2F;whatever is just one factor in that equation,
especially when it costs them other things they need.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;reliability-cost-value.png&quot; alt=&quot;Reliability vs other value factors on a balance scale&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔗 What defines reliability?</title>
        <published>2026-01-16T00:00:00+00:00</published>
        <updated>2026-01-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0285-what-defines-reliability/"/>
        <id>https://bec-systems.com/blog/0285-what-defines-reliability/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0285-what-defines-reliability/">&lt;p&gt;Reliability is a common concern - this thing is critical - it needs to work!&lt;&#x2F;p&gt;
&lt;p&gt;Many things affect the reliability of a system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bugs in software we write&lt;&#x2F;li&gt;
&lt;li&gt;Bugs in 3rd party components (OSS, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Hardware failures&lt;&#x2F;li&gt;
&lt;li&gt;Edge condition failures (things we have not tested)&lt;&#x2F;li&gt;
&lt;li&gt;Tolerance stack-ups&lt;&#x2F;li&gt;
&lt;li&gt;Damage in the field&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The list goes on …&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some common assumptions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Hardware is more reliable than software.&lt;&#x2F;li&gt;
&lt;li&gt;Safety certified operating systems are more reliable than non-certified.&lt;&#x2F;li&gt;
&lt;li&gt;US-made components are more reliable than those from other countries.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here’s the thing … for 99% of products, most of the above does not matter. The
&lt;strong&gt;most likely source of bugs and reliability problems is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0061-where-do-reliability-stability-problems-typically-come-from&#x2F;&quot;&gt;the stuff we did&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;.
If SafeRTOS is 99.999% verified and Zephyr is only 99.9% verified, it does not
make much difference if the software we wrote is only 90% verified. Likewise, if
the tricky analog hardware circuit has not been tested in every edge condition
and verified at every combination of component tolerances, it may not be as
reliable as a simpler RTOS application running in an MCU.&lt;&#x2F;p&gt;
&lt;p&gt;Practical reliability is what matters, not theoretical reliability. What defines
reliability in most systems is that the design can be verified. A common MCU and
RTOS (like Zephyr) has already been extensively verified and tested to be
reliable in most conditions by many different people. Writing a relatively
simple application on top of a complex, but verified system makes the job
easier. The difficult verification work gets pushed off on someone else. This
same analysis also applies to concerns like performance and security. The system
is only as good as the weakest link. Reliability does not always directly
correlate to system complexity, but rather what percent can be proven correct.&lt;&#x2F;p&gt;
&lt;p&gt;There are no easy answers here, but don’t strain at a gnat and swallow a camel -
latching onto theoretical reliability&#x2F;performance&#x2F;security&#x2F;whatever, but
ignoring the practical concerns.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-defines-reliability.png&quot; alt=&quot;What defines reliability&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Shipping faster - what are the stakes?</title>
        <published>2026-01-14T00:00:00+00:00</published>
        <updated>2026-01-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0284-shipping-faster-what-are-the-stakes/"/>
        <id>https://bec-systems.com/blog/0284-shipping-faster-what-are-the-stakes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0284-shipping-faster-what-are-the-stakes/">&lt;p&gt;What do project delays cost? The obvious thing is the loss of revenue. Time is
money.&lt;&#x2F;p&gt;
&lt;p&gt;However, there are other less tangible consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Customers lose interest.&lt;&#x2F;li&gt;
&lt;li&gt;Team loses motivation.&lt;&#x2F;li&gt;
&lt;li&gt;Supporting organizations (vendors&#x2F;communities) may not take the team as seriously.&lt;&#x2F;li&gt;
&lt;li&gt;Automating and improving the process never happens as there is more and more
pressure to ship and no time to do anything else.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Think of this as a flywheel, either speeding up or slowing down. The forces on this flywheel are imperceptible - a small push here, some
drag there.&lt;&#x2F;p&gt;
&lt;p&gt;The simplest way to speed up the product development flywheel is to ship faster
by focusing on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;#release&quot;&gt;quality releases&lt;&#x2F;a&gt;.
Start by shipping quality
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0281-standards-for-internal-vs-external-releases&#x2F;&quot;&gt;internal releases&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;shipping-faster-stakes.png&quot; alt=&quot;Product development flywheel with accelerating and drag forces&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 It is often more work to review something than to do it</title>
        <published>2026-01-13T00:00:00+00:00</published>
        <updated>2026-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0283-it-is-often-more-work-to-review-something-than-to-do-it/"/>
        <id>https://bec-systems.com/blog/0283-it-is-often-more-work-to-review-something-than-to-do-it/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0283-it-is-often-more-work-to-review-something-than-to-do-it/">&lt;p&gt;As an experienced person, I am sometimes called on to review something. This can
be a frustrating, seemingly hopeless task. With one developer, I commented that
he could write code faster than I could review it. While there are some issues
you can spot from a cursory look, most issues are subtle in nature—otherwise the
original designer would have probably caught them. Therefore, you pretty much
have to go through the entire design exercise again (especially with hardware)
to find issues. In many cases, it would have been faster to simply do it
yourself. This is the quandary many experienced developers find themselves in
when working with junior people. They are responsible (because they are the
reviewer), but feel helpless to ensure quality.&lt;&#x2F;p&gt;
&lt;p&gt;This is also the quandary we find ourselves in with AI. AI agents can write code
much faster than any human can practically review. Therefore, the thought that
“with AI code, as long as we review it, we’re good” is delusional. We might
pretend we are doing it, but deep inside we know we are not. AI coding has
brought this into stark reality.&lt;&#x2F;p&gt;
&lt;p&gt;Too often, reviewers receive schematics or source code with little context. What
are the goals? What is the spec? What trade-offs were considered? What
calculations were done? What edge conditions were considered? What is the
architecture? Details without the big-picture context are very difficult to work
with. While I’ve not often been party to formal code reviews in a meeting
context, I suspect these could work better than offline asynchronous reviews
because you can ask the designer questions and perhaps get some insight into the
potentially weak areas of the system.&lt;&#x2F;p&gt;
&lt;p&gt;There are ways we can help reviewers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clear documentation about the requirements located in the same repository as
the design&#x2F;code.&lt;&#x2F;li&gt;
&lt;li&gt;All assumptions, decisions, calculations, etc. are documented. With
schematics, as much of this as possible should be included directly in the
schematic. Use more pages if needed.&lt;&#x2F;li&gt;
&lt;li&gt;Architecture is clearly defined and documented.&lt;&#x2F;li&gt;
&lt;li&gt;All testing is documented.&lt;&#x2F;li&gt;
&lt;li&gt;All assumptions are documented.&lt;&#x2F;li&gt;
&lt;li&gt;Automated tests are created where possible.&lt;&#x2F;li&gt;
&lt;li&gt;Performance metrics and resource usage are documented and automatically tested
if possible.&lt;&#x2F;li&gt;
&lt;li&gt;Any concerns, potential weak spots, or things we’re not sure of are clearly
documented. Often the designer is the only one who has insight into this.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The point many miss here is that if we do the above, we’re mostly helping
ourselves 6 months from now.&lt;&#x2F;p&gt;
&lt;p&gt;As systems become more complex, it seems the only practical path forward is
automated testing. Chip designers figured this out a long time ago as the cost
of errors is high with full-custom silicon. Software developers are pretty good
at this with TDD (test-driven development). But, the industry needs to go one
step further and embrace end-to-end testing (which includes both hardware and
software). Perhaps the most important role of a reviewer going forward is to
ensure adequate documentation exists and tests are in place. Anything else is
futile and we’re just pretending.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;review-work-imbalance.png&quot; alt=&quot;Review work imbalance&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 How far do you take releases?</title>
        <published>2026-01-12T00:00:00+00:00</published>
        <updated>2026-01-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0282-how-far-do-you-take-releases/"/>
        <id>https://bec-systems.com/blog/0282-how-far-do-you-take-releases/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0282-how-far-do-you-take-releases/">&lt;p&gt;Thus far, we have defined a release as something that is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;useful and high-quality&lt;&#x2F;a&gt;.
Typically, we think of a release as something formal - v1.3.8 that is packaged,
built, and announced. But we can push this further. What about pull requests? Is
every pull request that is merged at the same standard? Or do we merge them and
hope that something later in the process will magically transform the work into
something better? “Later never comes” - especially in complex systems.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;how-far-do-you-take-releases.png&quot; alt=&quot;How far do you take releases?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Open-source projects have figured this out. The standard for getting a PR merged
is incredibly high in most projects. Why? Because there is no business pressure
to merge it, but rather the fear of having to maintain something that is
substandard. The maintainers are looking out for their own selfish interests,
but these interests happen to align with the realities of this kind of work.
Fixing something after the fact is so much harder than doing it right in the
first place. As a result, most OSS projects maintain fairly high quality at any
point in their development. This is one reason Arch Linux
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0125-how-can-arch-linux-get-by-without-releases&#x2F;&quot;&gt;works so well&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While there is a place for brainstorming, prototyping, experimenting, etc., this
will not get you very far developing a real product. The earlier you push the
“release mentality” into the development process, the faster you’ll move. Maybe
not in the initial steps, but for sure once you are a third of the way through
the development cycle. Do you want to save time on the first third, or the last
two thirds of the development cycle? Hint, the Law of Compounding is at work
here …&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;compounding-time-savings.png&quot; alt=&quot;Compounding time savings&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎯 Standards for internal vs external releases</title>
        <published>2026-01-09T00:00:00+00:00</published>
        <updated>2026-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0281-standards-for-internal-vs-external-releases/"/>
        <id>https://bec-systems.com/blog/0281-standards-for-internal-vs-external-releases/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0281-standards-for-internal-vs-external-releases/">&lt;p&gt;It is natural to think of internal releases as “low stakes” - if it crashes and
burns, no big deal. It’s just an experiment, right? Near production release,
we’ll toss it over the wall to QA&#x2F;Manufacturing and find all the issues.&lt;&#x2F;p&gt;
&lt;p&gt;This is partly true, and partly false. While it is true a product should get
better over the development cycle, it is helpful to apply the same standards for
internal releases as external for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It forces an emphasis on quality early.&lt;&#x2F;li&gt;
&lt;li&gt;It results in automated testing.&lt;&#x2F;li&gt;
&lt;li&gt;There will be fewer surprises late in the development cycle.&lt;&#x2F;li&gt;
&lt;li&gt;Integration with other groups happens earlier (Quality, Sales, Manufacturing,
Customers).&lt;&#x2F;li&gt;
&lt;li&gt;It is much easier to build prototypes when quality is high.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This does not mean the entire product needs to be perfect on day one - that is
impossible, as the product is not done - just the work already completed,
however small that may be. Is this tiny bit of work done to high standards? Is
it testable, manufacturable, etc.? Is it
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;useful&lt;&#x2F;a&gt; to someone?&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the thing - it is much easier to apply high standards to small bits of
work as you go, than retroactively fix it late in the game. It is not a waste of
time, rather it is only way that works in developing modern systems.&lt;&#x2F;p&gt;
&lt;p&gt;If internal releases are not at the same standard as external releases, they are
not releases, they are something else.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;internal-vs-external-releases.png&quot; alt=&quot;Internal vs External Releases&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📦 What do we release?</title>
        <published>2026-01-08T00:00:00+00:00</published>
        <updated>2026-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0280-what-do-we-release/"/>
        <id>https://bec-systems.com/blog/0280-what-do-we-release/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0280-what-do-we-release/">&lt;p&gt;&lt;strong&gt;Everything!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Documentation&lt;&#x2F;li&gt;
&lt;li&gt;Hardware&lt;&#x2F;li&gt;
&lt;li&gt;Software&lt;&#x2F;li&gt;
&lt;li&gt;Prototypes&lt;&#x2F;li&gt;
&lt;li&gt;Products&lt;&#x2F;li&gt;
&lt;li&gt;Lunch&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Engineering is fundamentally the act of creating something new. And that
something new needs to be useful to someone or something. And the way we deliver
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;“useful” is the release.&lt;&#x2F;a&gt;
If we’re not releasing, we’re not delivering.&lt;&#x2F;p&gt;
&lt;p&gt;We might be polishing, researching, thinking, perfecting, stalling, loafing,
dreaming, but we’re not delivering.&lt;&#x2F;p&gt;
&lt;p&gt;The “release” mindset brings the focus to delivering value.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-do-we-release.png&quot; alt=&quot;What do we release - items flowing into releases, delivering products, lunch, and value&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 A release is what unifies Engineering and Business</title>
        <published>2026-01-07T00:00:00+00:00</published>
        <updated>2026-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0279-a-release-is-what-unifies-engineering-and-business/"/>
        <id>https://bec-systems.com/blog/0279-a-release-is-what-unifies-engineering-and-business/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0279-a-release-is-what-unifies-engineering-and-business/">&lt;p&gt;Some feedback on yesterday’s post
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0278-what-is-a-release&#x2F;&quot;&gt;What is a release&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;What specifically flows into the two points? Value? Effort?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Perhaps a better way to phrase this is these are the two points of focus that
unify the development team with the rest of the business organization. And the
release is the container.&lt;&#x2F;p&gt;
&lt;p&gt;Documentation, specifications, innovation, new technology, etc. flow into the
&lt;strong&gt;useful&lt;&#x2F;strong&gt; point.&lt;&#x2F;p&gt;
&lt;p&gt;Testing and automation flow into the &lt;strong&gt;confidence&lt;&#x2F;strong&gt; point.&lt;&#x2F;p&gt;
&lt;p&gt;The business value that flows out of the &lt;strong&gt;useful&lt;&#x2F;strong&gt; point is user value, profit,
increasing sales, etc.&lt;&#x2F;p&gt;
&lt;p&gt;From the &lt;strong&gt;confidence&lt;&#x2F;strong&gt; point flows quality and responsiveness.&lt;&#x2F;p&gt;
&lt;p&gt;But these two points give us a simple way to focus and evaluate a release - is
it any good? Is everything we are doing as engineers contributing to these
points?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;release-unifies-engineering-business.png&quot; alt=&quot;Release unifies engineering and business&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📦 What is a release?</title>
        <published>2026-01-06T00:00:00+00:00</published>
        <updated>2026-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0278-what-is-a-release/"/>
        <id>https://bec-systems.com/blog/0278-what-is-a-release/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0278-what-is-a-release/">&lt;p&gt;There are two aspects of a product release:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Something &lt;strong&gt;useful&lt;&#x2F;strong&gt; that others can experience.&lt;&#x2F;li&gt;
&lt;li&gt;Produced with a high level of &lt;strong&gt;confidence&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Everything flows into these two points.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-is-a-release.png&quot; alt=&quot;What is a release&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Shipping faster leads to predictability</title>
        <published>2026-01-05T00:00:00+00:00</published>
        <updated>2026-01-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0277-shipping-faster-leads-to-predictability/"/>
        <id>https://bec-systems.com/blog/0277-shipping-faster-leads-to-predictability/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0277-shipping-faster-leads-to-predictability/">&lt;p&gt;Shipping faster does not only mean getting to v1.0 faster (or even on time), but
also many internal releases at a good rate. This is the &lt;strong&gt;only way&lt;&#x2F;strong&gt; to bring
predictability into the development process.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;shipping-faster-predictability.png&quot; alt=&quot;Shipping faster leads to predictability&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔗 Platform thinking does not mean we don&#x27;t use other platforms</title>
        <published>2026-01-02T00:00:00+00:00</published>
        <updated>2026-01-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0276-platform-thinking-does-not-mean-we-don-t-use-other-platforms/"/>
        <id>https://bec-systems.com/blog/0276-platform-thinking-does-not-mean-we-don-t-use-other-platforms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0276-platform-thinking-does-not-mean-we-don-t-use-other-platforms/">&lt;p&gt;On the contrary, platform thinking readily embraces other tools and platforms.
The difference is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;We add our own tooling, integration, and workflows into the mix.&lt;&#x2F;li&gt;
&lt;li&gt;We own the integration points so we can readily swap out&#x2F;in 3rd party
components as needed.&lt;&#x2F;li&gt;
&lt;li&gt;We are not overly dependent on someone else’s platform that we don’t have
control over.&lt;&#x2F;li&gt;
&lt;li&gt;We value openness and flexibility.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Too often, the tendency is to lean toward all-encompassing platforms that we
think will solve all of our problems. This rarely gets us to where we need to be
to provide exceptional value.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platform-integration.png&quot; alt=&quot;Platform integration concept&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 AI coding requires better inputs and robust verification</title>
        <published>2025-12-31T00:00:00+00:00</published>
        <updated>2025-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0275-ai-coding-requires-better-inputs-and-robust-verification/"/>
        <id>https://bec-systems.com/blog/0275-ai-coding-requires-better-inputs-and-robust-verification/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0275-ai-coding-requires-better-inputs-and-robust-verification/">&lt;p&gt;Some great feedback on
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0274-impressive-is-not-always-effective&#x2F;&quot;&gt;the previous post (Impressive is not always effective)&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“I agree. It would be interesting, however, to compare the progression of AI
code generation with that of compilers - were there star assembly-code
engineers saying that compilers were just a way to brute force the generation
of assembly code?”&lt;&#x2F;p&gt;
&lt;p&gt;“I feel like there is a fundamental difference — perhaps that AI always lacks
the determinism of a good compiler. And it can completely ignore the best of
documentation without throwing an error code.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Having lived through several of these transitions (Assembly -&amp;gt; C -&amp;gt; C++ -&amp;gt;
Python -&amp;gt; Go -&amp;gt; Rust -&amp;gt; Zig -&amp;gt; AI …) there are always those who prefer to
stick with the current technology thinking the new adds no value or is even
detrimental.&lt;&#x2F;p&gt;
&lt;p&gt;AI is more just an example in the original article as it can make an impressive
mess much quicker than any human. Humans can make messes as well (made plenty
myself). So the point is not so much that AI is bad (or good), but rather
question: “Are values in place?” And, is there a process&#x2F;system&#x2F;platform
(whatever you want to call it) to ensure these values happen. AI can do good
work with the proper constraints and workflows, as can humans. But neither does
very good work without them.&lt;&#x2F;p&gt;
&lt;p&gt;That all said, as the above feedback suggested, AI is much less deterministic
than any compiler (two consecutive runs do not produce the same result), thus
needs clear guidance and robust verification to ensure the end result is
quality. All this can be accomplished, but needs to be thought through.&lt;&#x2F;p&gt;
&lt;p&gt;While compile warnings, linters, code review, and unit tests help ensure
compiled code is quality, AI is a different beast. If humans are too slow to
write the code originally, they are for sure too slow to review it. It is like
reviewing machine code from compilers - at some point you need to trust the
compiler. The errors from AI generated code will likely be more architectural
deficiencies or logical errors at a macro level. Bad architecture can bury you
in technical debt, but it takes time - initially it works fine. Thus several
things are critical:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Getting started with a good architecture. AI can help with this, but an
experienced developer needs to have input.&lt;&#x2F;li&gt;
&lt;li&gt;Good, concise documentation. As opposed to machine generated code, humans can
review this.&lt;&#x2F;li&gt;
&lt;li&gt;Automated end-to-end testing is critical. This is the only way to prove and
maintain correctness.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With AI development, better inputs and more verification are critical. Trying to
work in the middle of the AI coding process is futile and exhausting. The
beginning and the end of the process need shored up. But this requires
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;claude-plugins&#x2F;blob&#x2F;main&#x2F;doc-driven-development&#x2F;README.md&quot;&gt;better workflows&lt;&#x2F;a&gt;
and more discipline. While undisciplined traditional development is a nightmare,
undisciplined AI development is a train wreck.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;ai-coding-verification.png&quot; alt=&quot;AI Coding Verification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✨ Impressive is not always effective</title>
        <published>2025-12-30T00:00:00+00:00</published>
        <updated>2025-12-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0274-impressive-is-not-always-effective/"/>
        <id>https://bec-systems.com/blog/0274-impressive-is-not-always-effective/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0274-impressive-is-not-always-effective/">&lt;p&gt;When AI generates something, the result is often “impressive.” We might marvel
at how quickly lots of code is generated that mostly works. Generated
documentation is extremely detailed and well formatted. AI-created diagrams are
colorful, use emojis effectively and every last detail is included. However,
“impressive” is often the antithesis of “effective” for one simple reason -
simplicity is missing.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It is difficult to understand the architecture of the code because there is so
much of it.&lt;&#x2F;li&gt;
&lt;li&gt;“Why” is nearly impossible to draw from the expansive details in the
documentation. Who has time to dig it out?&lt;&#x2F;li&gt;
&lt;li&gt;A quick glance at a diagram reveals nothing about the big-picture without
laboriously processing many details.&lt;&#x2F;li&gt;
&lt;li&gt;The complexity of machine-generated designs is often a brute-force approach
that lacks style, elegance, and consistency.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Architecture, Why, Big-picture, and Elegance - these are still the foundations
of great work. Learn to look past impressive things. Is the architecture clear?
Are the reasons obvious? Is it easy to understand at a high-level what is going
on? Is the design and implementation clean and simple? There are two paths:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;“Impressive” is the route to compounding technical debt.&lt;&#x2F;li&gt;
&lt;li&gt;“Effective” is the only way to compounding improvements.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;impressive-vs-effective.png&quot; alt=&quot;Impressive vs Effective&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🥄 The beauty of human creativity</title>
        <published>2025-12-29T00:00:00+00:00</published>
        <updated>2025-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0273-the-beauty-of-human-creativity/"/>
        <id>https://bec-systems.com/blog/0273-the-beauty-of-human-creativity/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0273-the-beauty-of-human-creativity/">&lt;p&gt;In this age of machine-generated perfection, something is still deeply rewarding
about grabbing a stick of wood and making something by hand. This past
Christmas, with the help of kids and grandkids, we made a few mixing spoons for
gifts. Starting from the same pattern but with varying levels of skill and
technique, each spoon turned out a bit different. However, each one is special
and beautiful because it has a human touch. And sometimes with variety and
imperfection, a new pattern emerges that actually works better. This is one
source of innovation.&lt;&#x2F;p&gt;
&lt;p&gt;In an age of AI-generated code, preserving the human touch remains important.
Perhaps it is the well-thought-out documentation that explains exactly how this
feature will help the user. Or the hand-coded API that is a pleasure to use.
Explorations in new data structures and algorithms coded by hand sometimes
result in amazing discoveries because thinking accompanies the creative process.
Machines (including AI) can mostly only do what has been done before. But the
real value lies in the new connections, the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0124-truth-is-discovered-not-invented&#x2F;&quot;&gt;newly discovered truths&lt;&#x2F;a&gt;,
the well-understood needs of the user, and the exceptional quality. These still
require human impetus.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;spoons.png&quot; alt=&quot;image-20251229211200569&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📖 The definition of the word &#x27;Platform&#x27;</title>
        <published>2025-12-24T00:00:00+00:00</published>
        <updated>2025-12-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0272-the-definition-of-the-word-platform/"/>
        <id>https://bec-systems.com/blog/0272-the-definition-of-the-word-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0272-the-definition-of-the-word-platform/">&lt;p&gt;The definition of the word “platform” includes things like the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Acts as foundational for other products or services, not the final end product
itself.&lt;&#x2F;li&gt;
&lt;li&gt;Provides a stable base.&lt;&#x2F;li&gt;
&lt;li&gt;Typically supports multiple, distinct applications or use cases.&lt;&#x2F;li&gt;
&lt;li&gt;A formal declaration of the principles of a group.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What are the aspects of a physical platform?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provide a supporting surface: Examples include train station platforms,
stages, loading docks, scaffolds, and cargo pallets, all of which physically
support people or objects at a useful height or position.&lt;&#x2F;li&gt;
&lt;li&gt;Enable safe and efficient interaction: Platforms make boarding, loading,
performing, or working safer and more efficient by aligning heights, improving
visibility, and organizing space.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Stable, foundational, supportive, efficient, visibility, safety, organization
… does this provide any inspiration for YOUR Platform?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;definition-of-platform.png&quot; alt=&quot;A platform supporting multiple products and services&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Platform Thinking is a habit</title>
        <published>2025-12-23T00:00:00+00:00</published>
        <updated>2025-12-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0271-platform-thinking-is-a-habit/"/>
        <id>https://bec-systems.com/blog/0271-platform-thinking-is-a-habit/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0271-platform-thinking-is-a-habit/">&lt;p&gt;Platform Thinking in the context of product development has many parallels to
effective habits in personal life. With personal exercise, healthy eating, getting
enough sleep, and reading good books - these are difficult to start, but easy once
started, and rewarding once finished. These things work best when they are
habits - a regular behavior pattern that a person tends to do automatically,
often without much thought.&lt;&#x2F;p&gt;
&lt;p&gt;Documentation, testing, and automation in a product development context are
similar. It won’t just happen. A framework is required to nudge us into a
pattern that turns into an effective habit. In many ways, Platform Thinking is
just &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jamesclear.com&#x2F;atomic-habits&quot;&gt;Atomic Habits&lt;&#x2F;a&gt; for product
development teams.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platform-thinking-habit.png&quot; alt=&quot;Platform Thinking is a habit - showing parallel between personal habits like exercise, healthy eating, sleep, and reading with platform thinking habits like documentation, testing, automation, and process&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎯 Who is Platform Thinking for?</title>
        <published>2025-12-22T00:00:00+00:00</published>
        <updated>2025-12-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0270-who-is-platform-thinking-for/"/>
        <id>https://bec-systems.com/blog/0270-who-is-platform-thinking-for/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0270-who-is-platform-thinking-for/">&lt;p&gt;Platform Thinking is for anyone who wants to take the friction out of creating,
publishing, testing, integrating, and deploying products.&lt;&#x2F;p&gt;
&lt;p&gt;The result? Value. Quality. Timeliness.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platform-thinking-for.png&quot; alt=&quot;Platform Thinking removes friction from creating, publishing, testing, integrating, and deploying to deliver value, quality, and timeliness&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⏳ The long-term compression timeline</title>
        <published>2025-12-18T00:00:00+00:00</published>
        <updated>2025-12-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0269-the-long-term-compression-timeline/"/>
        <id>https://bec-systems.com/blog/0269-the-long-term-compression-timeline/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0269-the-long-term-compression-timeline/">&lt;p&gt;Below are several timelines illustrating
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0257-the-long-term-may-be-closer-than-you-think&#x2F;&quot;&gt;long-term compression&lt;&#x2F;a&gt;
comparing a product development timeline:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;20 years ago&lt;&#x2F;li&gt;
&lt;li&gt;Today&lt;&#x2F;li&gt;
&lt;li&gt;Today with Platform Thinking&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The big effect of long-term compression is that negative consequences can hit
much earlier, delaying initial shipment (the middle timeline).&lt;&#x2F;p&gt;
&lt;p&gt;While it is very difficult to compress a product development timeline to initial
release, with Platform Thinking, v1.0 can still arrive in a year as in the olden
days. The big difference is subsequent releases ship much quicker than in any
previous scenario.&lt;&#x2F;p&gt;
&lt;p&gt;So while the complexity of modern technology presents new challenges and
requires a different approach, leveraging technology to build a platform can
produce even better results than any previous scenario.&lt;&#x2F;p&gt;
&lt;p&gt;Long-term compression can have both compounding negative or compounding positive
effects. Both the negative costs and the positive benefits come back much
quicker. Which comes back depends on YOUR Platform.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;timeline-compression.png&quot; alt=&quot;timeline compression&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🗜️ Long-term compression</title>
        <published>2025-12-17T00:00:00+00:00</published>
        <updated>2025-12-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0268-long-term-compression/"/>
        <id>https://bec-systems.com/blog/0268-long-term-compression/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0268-long-term-compression/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;long-term-compression.png&quot; alt=&quot;Long-term compression - comparing traditional mindset, today’s compressed timeline reality, and platform thinking approach&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One reality of developing products with modern technology is the compression of
the short and long-term. Today, the consequences of actions come back on the
timeframe of months instead of years, as it might have been ten or twenty years
ago. No longer does it work to take shortcuts with the hope of shipping v1.0,
making some money, and cleaning things up later. The product may never even see
v1.0.&lt;&#x2F;p&gt;
&lt;p&gt;This is why YOUR Platform is so important. Platform thinking enables you to
reach the v1.0 release in a timely manner, and efficiently maintain and improve
beyond that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Platforms are not just for developers</title>
        <published>2025-12-16T00:00:00+00:00</published>
        <updated>2025-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0267-platforms-are-not-just-for-developers/"/>
        <id>https://bec-systems.com/blog/0267-platforms-are-not-just-for-developers/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0267-platforms-are-not-just-for-developers/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platforms-not-just-for-developers.png&quot; alt=&quot;Platforms are not just for developers&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is an
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;feed&#x2F;update&#x2F;urn:li:activity:7404499127998402562&#x2F;&quot;&gt;interesting post&lt;&#x2F;a&gt;
from a Marketing person creating website pages:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I built 19 website pages in a single day while my team was out for US
thanksgiving. Not mockups. Not placeholders. Actual, shippable pages: a full
partner ecosystem landing page plus individual pages for every major partner
we’re building with right now. It felt surreal. Mostly because &lt;strong&gt;a year+ ago,
there’s no universe in which I would’ve believed I could do that&lt;&#x2F;strong&gt;. And it
definitely wouldn’t have happened without the engineers around me who’ve
taught me how to think more like a builder—patiently walking me through GitHub
(😒), tools, workflows, and a way of working that used to feel miles outside
my world.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I then asked how long it took before she stopped hating Git?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I mean it took about 5 pull requests before I finally managed to create one
without an error 🥵… it’s been two weeks and I finally feel like the
lightbulbs are going off and I’m understanding the flow (pulling things from
main, branches, commits, PRs, basic commands I have on a sticky note lol,
etc).&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is a great example of someone who took ownership of their website creation,
editing, and publishing workflow. Using
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0242-local-first-dev&#x2F;&quot;&gt;local files&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0191-text-based-formats-and-command-line-tools-are-the-future&#x2F;&quot;&gt;text based formats&lt;&#x2F;a&gt;
unleashed the power of AI resulting in the productivity described above. Using
AI,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0210-anyone-can-write-scripts-now&#x2F;&quot;&gt;anyone can now write scripts&lt;&#x2F;a&gt;,
create web pages, and code to some level. Text based formats and command-line
tools are now within reach for anyone willing to learn a bit. All it takes is a
willingness to break out of the cozy cocoon of GUI based tools, learn how to use
an editor and terminal, and invest a little effort in creating a workflow.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Breaking the AI slop cycle</title>
        <published>2025-12-15T00:00:00+00:00</published>
        <updated>2025-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0266-breaking-the-ai-slop-cycle/"/>
        <id>https://bec-systems.com/blog/0266-breaking-the-ai-slop-cycle/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0266-breaking-the-ai-slop-cycle/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;breaking-ai-slop-cycle.png&quot; alt=&quot;Breaking the AI Slop Cycle&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;“AI Slop” is a common expression describing a familiar phenomenon. It refers to
sloppy code (or other assets) generated by AI that mostly works, lacks proper
review, and may be poorly architected or implemented. The primary characteristic
of AI Slop is that it is hard to read, understand, and maintain.&lt;&#x2F;p&gt;
&lt;p&gt;Like anything else, fixing problems early in the cycle works best—not generating
slop in the first place instead of trying to clean it up later. Even AI tools,
as powerful as they are, have trouble cleaning up slop. Once the slop is cast in
code, AI (like a human) is very reluctant to throw away all the hard work and
start over.&lt;&#x2F;p&gt;
&lt;p&gt;So how does one break the cycle? The best method I’ve found is a lightweight
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;claude-plugins&#x2F;blob&#x2F;main&#x2F;doc-driven-development&#x2F;README.md&quot;&gt;formal documentation and planning workflow&lt;&#x2F;a&gt;.
The documentation ensures good thinking about what the problem is, what needs to
be built, and why. The planning stage helps ensure the architecture is good. It
is much easier to think about and rework a plan than code.&lt;&#x2F;p&gt;
&lt;p&gt;The documentation&#x2F;planning steps also clearly delineate the responsibility of
humans and AI. While AI can help explore options, it still does not have the
entire context that humans have when it comes to clearly defining the problem.&lt;&#x2F;p&gt;
&lt;p&gt;When slop appears, this means the up-front thinking was not very good. One of
the most useful skills when working with AI is recognizing when the slop zone is
approaching, backing up, and getting more formal.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤔 Isn&#x27;t this just agile?</title>
        <published>2025-12-12T00:00:00+00:00</published>
        <updated>2025-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0265-isn-t-this-just-agile/"/>
        <id>https://bec-systems.com/blog/0265-isn-t-this-just-agile/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0265-isn-t-this-just-agile/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;agile-vs-platform-thinking.png&quot; alt=&quot;Agile vs Platform Thinking comparison&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A reader responded to the last post with a comment:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Isn’t “agile” a part of product thinking too? That doesn’t seem linear?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is a good question. Agile covers a lot of ground. The Agile Manifesto
states:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;We are uncovering better ways of developing software by doing it and helping
others do it. Through this work we have come to value:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Individuals and interactions over processes and tools&lt;&#x2F;li&gt;
&lt;li&gt;Working software over comprehensive documentation&lt;&#x2F;li&gt;
&lt;li&gt;Customer collaboration over contract negotiation&lt;&#x2F;li&gt;
&lt;li&gt;Responding to change over following a plan&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That is, while there is value in the items on the right, we value the items on
the left more.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Typically agile focuses on fast iterations and quick feedback, which is
definitely part of platform thinking. Most software methodologies focus on
creating software. Platform thinking expands to include more of product
development including mechanical, hardware, and integration. Much of development
these days is integration of complex systems, including vast amounts of
open-source software. As system complexity grows, teams need ways to deal with
this complexity. Individual interactions are great and very important, but they
don’t scale with complexity. And perhaps the real goal of YOUR Platform is to
free people from tedious repetitious work, so individuals will have more time to
interact in creative ways.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏗️ Platform thinking vs 📦 Product thinking</title>
        <published>2025-12-10T00:00:00+00:00</published>
        <updated>2025-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0264-platform-thinking-vs-product-thinking/"/>
        <id>https://bec-systems.com/blog/0264-platform-thinking-vs-product-thinking/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0264-platform-thinking-vs-product-thinking/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platform-vs-product-thinking.png&quot; alt=&quot;Platform thinking vs Product thinking&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Platform vs. product thinking is a difference in perspective. Platform thinking
does not ignore the product, but rather approaches it from a slightly different
angle.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏆 What is the ultimate platform success?</title>
        <published>2025-12-09T00:00:00+00:00</published>
        <updated>2025-12-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0263-what-is-the-ultimate-platform-success/"/>
        <id>https://bec-systems.com/blog/0263-what-is-the-ultimate-platform-success/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0263-what-is-the-ultimate-platform-success/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platform-success-evolution.png&quot; alt=&quot;Platform success evolution diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The ultimate platform success is when an internal platform turns into a sellable
product&#x2F;service, or an open source project.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps some companies succeed by starting out building a platform as a product,
but the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;provide-examples-of-commercial-35vCdIRBSMWQOW0rYlu2yg&quot;&gt;greatest platform successes&lt;&#x2F;a&gt;
started as internal platforms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;AWS&lt;&#x2F;li&gt;
&lt;li&gt;Kafka&lt;&#x2F;li&gt;
&lt;li&gt;Kubernetes&lt;&#x2F;li&gt;
&lt;li&gt;Slack&lt;&#x2F;li&gt;
&lt;li&gt;Shopify&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Why does this work? Perhaps because developers building internal platforms have
the “platform mindset.” Starting out building a platform to sell means building
with the “product” mindset instead of the “platform” mindset.&lt;&#x2F;p&gt;
&lt;p&gt;Compare AWS, Azure, and GCP. Amazon and Microsoft use these platforms
extensively internally. Google
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;inside-googles-engineering-culture&#x2F;1599&#x2F;3?u=cbrake&quot;&gt;does not&lt;&#x2F;a&gt;.
Google likely has valid reasons for this as GCP is not their primary product
(compared to search, YouTube, etc.). But the results speak for themselves:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;&#x2F;th&gt;&lt;th&gt;&lt;strong&gt;AWS (Amazon)&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Microsoft Azure&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Google Cloud (GCP)&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Market Share&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;~29-31%&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;~20%&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;~13%&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Revenue Run Rate&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;~$132 Billion&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;~$123 Billion&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;~$61 Billion&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Primary Internal Use&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;High.&lt;&#x2F;strong&gt; Amazon.com is heavily migrated to AWS, including retail databases and Prime Video.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;High.&lt;&#x2F;strong&gt; LinkedIn, Office 365, and GitHub are actively migrating or fully migrated to Azure.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Mixed.&lt;&#x2F;strong&gt; Core search&#x2F;ads&#x2F;YouTube&#x2F;Gmail&#x2F;Docs runs on internal-only PROD infrastructure.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔀 The division between group and personal workflow</title>
        <published>2025-12-05T00:00:00+00:00</published>
        <updated>2025-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0262-the-division-between-group-and-personal-workflow/"/>
        <id>https://bec-systems.com/blog/0262-the-division-between-group-and-personal-workflow/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0262-the-division-between-group-and-personal-workflow/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;personal-group-workflow-division.png&quot; alt=&quot;Personal and Group Workflow Division&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When thinking about developer workflows, tools, and resources, dividing them
into two categories proves useful: &lt;strong&gt;personal&lt;&#x2F;strong&gt; and &lt;strong&gt;group&lt;&#x2F;strong&gt;. A group resource
is something that multiple people use (or should use): SDKs, libraries, linters,
formatters, AI commands&#x2F;context, etc. Personal tools are things that others do
not use: pencil, computer, phone, editor, notes system, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Why is this so important? Why not just make it simple and force everyone to use
the same computer, editor, notes system, chair, desk, etc.?&lt;&#x2F;p&gt;
&lt;p&gt;Humans are users and creators of tools—naturally inclined to make, modify, and
optimize tools for specific needs. Innovation happens where there is freedom.
Many improvements start from a single person scratching their own itch. Over
time it becomes apparent that a tool or improvement will benefit the group, so
it migrates to a container or some other shared resource and is integrated into
the group workflow.&lt;&#x2F;p&gt;
&lt;p&gt;As previously mentioned, any shared resource should
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0261-cdpd-container-driven-product-development&#x2F;&quot;&gt;be containerized&lt;&#x2F;a&gt;
when possible. Containers allow the personal computer to be the dividing line
between personal and group workflows.&lt;&#x2F;p&gt;
&lt;p&gt;No two humans do exactly the same thing. No two humans think and work in exactly
the same way. While there are many benefits to having group workflows, the
personal workflows must also be nourished, as these are a primary source of
innovation. The key is to have a culture where the migration from personal
workflow to group workflow is encouraged, supported, and rewarded.&lt;&#x2F;p&gt;
&lt;p&gt;To scale, an organization must have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A clear division between personal and group workflows.&lt;&#x2F;li&gt;
&lt;li&gt;An efficient way to reuse personal workflows as group workflows where
appropriate.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📦 CDPD - Container Driven Product Development</title>
        <published>2025-12-04T00:00:00+00:00</published>
        <updated>2025-12-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0261-cdpd-container-driven-product-development/"/>
        <id>https://bec-systems.com/blog/0261-cdpd-container-driven-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0261-cdpd-container-driven-product-development/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;cdpd-workflow.png&quot; alt=&quot;Container Driven Product Development workflow comparing traditional scattered tools vs containerized approach&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When updating the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;&quot;&gt;Simple IoT documentation&lt;&#x2F;a&gt;, the
question arose - how to install &lt;code&gt;mdbook&lt;&#x2F;code&gt; and a few plugins? Of course &lt;code&gt;pacman&lt;&#x2F;code&gt;
has part of what is needed. In the past &lt;code&gt;cargo&lt;&#x2F;code&gt; has been used, but that is slow
and not a good fit for shared tools. Then it became clear:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Any shared tools used by the team (build, linting, formatting, CI&#x2F;CD) etc.
should be put in containers up front (before development starts)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;.. and use them for development builds as well as CI&#x2F;CD.
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;docker-mdbook&quot;&gt;this container&lt;&#x2F;a&gt; is the result)&lt;&#x2F;p&gt;
&lt;p&gt;Why?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It is pretty easy these days with Claude Code.&lt;&#x2F;li&gt;
&lt;li&gt;Gitea, GitHub, and likely other Git hosting platforms now provide convenient
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.gitea.com&#x2F;usage&#x2F;packages&#x2F;overview&quot;&gt;“package” registries&lt;&#x2F;a&gt;. You no
longer need to go through the hassle of using the Docker registry.&lt;&#x2F;li&gt;
&lt;li&gt;It is easy to onboard new devs - no need to spend time installing SDKs and a
host of tools.&lt;&#x2F;li&gt;
&lt;li&gt;Versions are locked down, eliminating the possibility of different people
using different versions.&lt;&#x2F;li&gt;
&lt;li&gt;They get exercised a lot, so quality is high.&lt;&#x2F;li&gt;
&lt;li&gt;It is much easier to move into CI&#x2F;CD.&lt;&#x2F;li&gt;
&lt;li&gt;A Dockerfile is easier to maintain than a long document describing how to
manually install all the tools needed.&lt;&#x2F;li&gt;
&lt;li&gt;NPM and Python packages are a pain to install locally, so why not just
eliminate that pain?&lt;&#x2F;li&gt;
&lt;li&gt;It is easier to get everyone on the team using the entire toolset (linting,
formatting, etc.).&lt;&#x2F;li&gt;
&lt;li&gt;No longer fighting differences between developers’ machines. If one developer
wants to run Arch and another Ubuntu, no problem.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Developers are still free to use their favorite editor, Git client, and other
local tools.&lt;&#x2F;p&gt;
&lt;p&gt;This is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0256-ddpd-tdpd-rdpd&#x2F;&quot;&gt;another case&lt;&#x2F;a&gt; where
a little time spent up front is quickly regained, then compounded by not
continually redoing stuff, and fighting problems that can be solved once.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 Tips for working with Markdown</title>
        <published>2025-11-26T00:00:00+00:00</published>
        <updated>2025-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0260-tips-for-working-with-markdown/"/>
        <id>https://bec-systems.com/blog/0260-tips-for-working-with-markdown/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0260-tips-for-working-with-markdown/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;markdown-workflow.png&quot; alt=&quot;Markdown Workflow &amp;amp; Tools&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Markdown is now a nearly universal format for documentation in many workflows.
A few tips for being effective with Markdown:&lt;&#x2F;p&gt;
&lt;p&gt;Use a standard editor most of the time (VS Code, Vim, Helix, etc.). This is
faster than graphical “Markdown” editors for most things. Additionally, this
builds familiarity with Markdown formatting codes, which aids in creating nicely
formatted comments in Jira, GitHub, Trello, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;typora.io&#x2F;&quot;&gt;Typora&lt;&#x2F;a&gt; to create more complex things like tables and
images. This tool is well worth the few $ it costs.&lt;&#x2F;p&gt;
&lt;p&gt;Put images in an &lt;code&gt;&#x2F;assets&lt;&#x2F;code&gt; sub-directory and name image files descriptively
(Typora makes this easy).&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;prettier.io&#x2F;&quot;&gt;prettier&lt;&#x2F;a&gt; to format the file and wrap long lines. Add
a &lt;code&gt;.prettierrc&lt;&#x2F;code&gt; to every repo with the following contents: &lt;code&gt;proseWrap: always&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;writewithharper.com&#x2F;&quot;&gt;Harper&lt;&#x2F;a&gt;
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;writewithharper.com&#x2F;docs&#x2F;integrations&#x2F;language-server&quot;&gt;language server&lt;&#x2F;a&gt;
in your editor is best) to check for grammar and formatting issues. One
unexpected side effect of this is that it encourages marking technical words
that don’t have standard spelling as code, rather than adding them all to your
dictionary.&lt;&#x2F;p&gt;
&lt;p&gt;Add dictionary words to a &lt;code&gt;.harper-dictionary.txt&lt;&#x2F;code&gt; in the repo that contains the
markdown file. This way others can benefit from a common dictionary. Again, this
is easy with a &lt;code&gt;harper-ls&lt;&#x2F;code&gt; quick-action.&lt;&#x2F;p&gt;
&lt;p&gt;Add a TOC if the file is long (the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;writewithharper.com&#x2F;docs&#x2F;integrations&#x2F;language-server&quot;&gt;&lt;code&gt;harper-ls&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
quick-action makes this easy).&lt;&#x2F;p&gt;
&lt;p&gt;Use the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;artempyanykh&#x2F;marksman&quot;&gt;Marksman&lt;&#x2F;a&gt; language server.
This makes navigating and refactoring in your editor easy.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;markdown-here.com&#x2F;&quot;&gt;Markdown Here&lt;&#x2F;a&gt; or
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;addons.thunderbird.net&#x2F;en-US&#x2F;thunderbird&#x2F;addon&#x2F;markdown-here-revival&#x2F;&quot;&gt;Markdown Here Revival&lt;&#x2F;a&gt;
in your browser or email client to write better emails.&lt;&#x2F;p&gt;
&lt;p&gt;While Markdown has its formatting limitations, with a little tooling it is much
easier and faster to work with than anything else.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤔 Why &gt; How &gt; What</title>
        <published>2025-11-25T00:00:00+00:00</published>
        <updated>2025-11-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0259-why-how-what/"/>
        <id>https://bec-systems.com/blog/0259-why-how-what/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0259-why-how-what/">&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Why?&lt;&#x2F;strong&gt; Is this the right thing to build?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How?&lt;&#x2F;strong&gt; Can it be done efficiently, repeatedly?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;What?&lt;&#x2F;strong&gt; The deliverable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These are listed in order of importance, which also corresponds to the level of
difficulty.&lt;&#x2F;p&gt;
&lt;p&gt;The trouble with “How” and “Why” is these are less visible, which contributes to
their difficulty as it takes discipline to prioritize and do them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;what-how-why.png&quot; alt=&quot;why-how-what&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🥉 Good, fast, cheap - choose three</title>
        <published>2025-11-24T00:00:00+00:00</published>
        <updated>2025-11-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0258-good-fast-cheap-choose-three/"/>
        <id>https://bec-systems.com/blog/0258-good-fast-cheap-choose-three/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0258-good-fast-cheap-choose-three/">&lt;p&gt;A familiar phrase states:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Good, fast, cheap. Choose two.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is similar to the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;development-triangle&#x2F;71&quot;&gt;development triangle&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;development-triangle.png&quot; alt=&quot;dev triangle&quot; style=&quot;zoom:100%;&quot; &#x2F;&gt;
&lt;p&gt;Which states that everything is a tradeoff.&lt;&#x2F;p&gt;
&lt;p&gt;However, improving all three becomes possible when doing things differently.
That is the fundamental purpose of YOUR platform - to improve “how” teams build
things. To develop a synergistic relationship between
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0256-ddpd-tdpd-rdpd&#x2F;&quot;&gt;value, timeliness, and quality,&lt;&#x2F;a&gt;
without compromise.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;ddpd-tdpd-rdpd.png&quot; alt=&quot;all three&quot; style=&quot;zoom:35%;&quot; &#x2F;&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⏳ The &quot;long-term&quot; may be closer than you think...</title>
        <published>2025-11-21T00:00:00+00:00</published>
        <updated>2025-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0257-the-long-term-may-be-closer-than-you-think/"/>
        <id>https://bec-systems.com/blog/0257-the-long-term-may-be-closer-than-you-think/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0257-the-long-term-may-be-closer-than-you-think/">&lt;p&gt;A common objection to “Platform Thinking” (proactively build your platform
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0256-ddpd-tdpd-rdpd&#x2F;&quot;&gt;from the start&lt;&#x2F;a&gt;) is: there
isn’t time right now; this can be done after the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0251-the-big-release-vs-a-continuous-flow-of-value&#x2F;&quot;&gt;1.0 release&lt;&#x2F;a&gt;
when there is ample time and resources.&lt;&#x2F;p&gt;
&lt;p&gt;The “long-term” can be defined as when the consequences of actions come back -
when the seeds sown are reaped.&lt;&#x2F;p&gt;
&lt;p&gt;When building complex systems with modern technology, the gap between the short-
and long-term is &lt;strong&gt;months instead of years&lt;&#x2F;strong&gt;. There is a compression of the
short- and long-term. Neglecting the platform may have worked a decade or two
ago, but with the complexity of even basic embedded systems today (Zephyr,
Embedded Linux, connectivity, data, etc.), the “long-term” is much more
imminent. The pain from shortcuts emerges in months instead of years. The slope
of the technical debt curve is much steeper.&lt;&#x2F;p&gt;
&lt;p&gt;The reality with complex systems today is there is no short- and long-term -
they have morphed into one and the same. Without building for the long-term now,
there will not be even a short-term, let alone a long-term.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;short-long-term-compression.png&quot; alt=&quot;short&#x2F;long compression&quot; style=&quot;zoom:50%;&quot; &#x2F;&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 DDPD - 🧪 TDPD - 🚀 RDPD</title>
        <published>2025-11-20T00:00:00+00:00</published>
        <updated>2025-11-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0256-ddpd-tdpd-rdpd/"/>
        <id>https://bec-systems.com/blog/0256-ddpd-tdpd-rdpd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0256-ddpd-tdpd-rdpd/">&lt;p&gt;We have been discussing document, test, and release-driven development (doing
these things first before implementing features).&lt;&#x2F;p&gt;
&lt;p&gt;This ensures the product:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Meets the customer’s needs
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0255-ddpd-document-driven-product-development&#x2F;&quot;&gt;DDPD&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Is quality (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0253-tdpd&#x2F;&quot;&gt;TDPD&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Can be modified any time and released quickly
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0254-rdpd&#x2F;&quot;&gt;RDPD&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Without these, teams can quickly become buried in mundane repetitive work, bugs,
and technical debt.&lt;&#x2F;p&gt;
&lt;p&gt;But perhaps the less obvious fact is these things often go undone if not
prioritized from the start. Why? Because once a feature is done, there is
pressure to move on to the next one. There is no time for “cleaning things up.”
To ensure these things happen, they must be done first.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;ddpd-tdpd-rdpd.png&quot; alt=&quot;image-20251120101418691&quot; style=&quot;zoom:50%;&quot; &#x2F;&gt;
&lt;p&gt;(2025-12-05 update: And we now also have
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0261-cdpd-container-driven-product-development&#x2F;&quot;&gt;CDPD&lt;&#x2F;a&gt;.)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 DDPD - Document Driven Product Development</title>
        <published>2025-11-17T00:00:00+00:00</published>
        <updated>2025-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0255-ddpd-document-driven-product-development/"/>
        <id>https://bec-systems.com/blog/0255-ddpd-document-driven-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0255-ddpd-document-driven-product-development/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;ddpd.png&quot; alt=&quot;ddpd&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Building on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0253-tdpd&#x2F;&quot;&gt;TDPD&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0254-rdpd&#x2F;&quot;&gt;RDPD&lt;&#x2F;a&gt;, Document-driven product
development (DDPD) offers another perspective.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Ideas:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Document the feature from the user’s perspective before implementing anything.&lt;&#x2F;li&gt;
&lt;li&gt;Keep the documentation close to the code (same repo, etc.).&lt;&#x2F;li&gt;
&lt;li&gt;Use a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;claude-plugins&#x2F;blob&#x2F;main&#x2F;doc-driven-development&#x2F;README.md&quot;&gt;doc-driven&lt;&#x2F;a&gt;
AI plugin when applicable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Benefits:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Better thought-through features.&lt;&#x2F;li&gt;
&lt;li&gt;Non-technical people can review before implementation.&lt;&#x2F;li&gt;
&lt;li&gt;Higher likelihood of implementing what users actually need.&lt;&#x2F;li&gt;
&lt;li&gt;Documentation becomes a pleasant&#x2F;creative&#x2F;thinking task, rather than a boring
requirement after implementation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 RDPD - Release Driven Product Development</title>
        <published>2025-11-13T00:00:00+00:00</published>
        <updated>2025-11-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0254-rdpd/"/>
        <id>https://bec-systems.com/blog/0254-rdpd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0254-rdpd/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;rdpd.png&quot; alt=&quot;rdpd&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yesterday we talked about
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0253-tdpd&#x2F;&quot;&gt;Test-Driven Product Development&lt;&#x2F;a&gt;.
Release-driven product development is another perspective.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Build the release&#x2F;deployment mechanism before implementing the design.&lt;&#x2F;li&gt;
&lt;li&gt;Automate as much of the release as possible.&lt;&#x2F;li&gt;
&lt;li&gt;This includes all assets needed to build&#x2F;deploy the product.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While this idea is somewhat common in cloud software (continuous delivery),
embedded, hardware, and mechanical release mechanisms are usually lacking.&lt;&#x2F;p&gt;
&lt;p&gt;The benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;More prototypes will be built (because it is easy).&lt;&#x2F;li&gt;
&lt;li&gt;More testing will occur early (because prototypes are available).&lt;&#x2F;li&gt;
&lt;li&gt;Lots will be learned (happens when people are using prototypes).&lt;&#x2F;li&gt;
&lt;li&gt;Releasing to manufacturing becomes easy (because it has already been done many
times).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Implementing release mechanisms first is a strategic approach, because without
doing it first, it likely won’t get done. Once something is “finished,” there is
pressure (from above) to move on to the next development.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧪 TDPD - Test Driven Product Development</title>
        <published>2025-11-12T00:00:00+00:00</published>
        <updated>2025-11-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0253-tdpd/"/>
        <id>https://bec-systems.com/blog/0253-tdpd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0253-tdpd/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tdpd.png&quot; alt=&quot;tdpd&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We’re familiar with TDD (test-driven development) in the software world.
Basically the idea is to create unit tests before implementing a feature.&lt;&#x2F;p&gt;
&lt;p&gt;What if we extend this to systems, hardware, and even mechanical?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Write end-to-end system tests before developing a feature.&lt;&#x2F;li&gt;
&lt;li&gt;Design&#x2F;build test fixtures before designing the PCB. PCBs are
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0186-how-to-iterate-quickly-on-hardware&#x2F;&quot;&gt;cheap and fast&lt;&#x2F;a&gt;
to build now - so build an additional one for testing.&lt;&#x2F;li&gt;
&lt;li&gt;Create automated checks on 3D CAD models for fit&#x2F;clearance, etc. Does the new
PCB fit in the product?&lt;&#x2F;li&gt;
&lt;li&gt;Do you have additional ideas?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And then automate all these so they run continually. This takes the tedium out
of testing and helps ensure every development change is a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0251-the-big-release-vs-a-continuous-flow-of-value&#x2F;&quot;&gt;BIG Release&lt;&#x2F;a&gt;.
Testing first also leads to better design.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🍄 Mushroom Management</title>
        <published>2025-11-07T00:00:00+00:00</published>
        <updated>2025-11-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0252-mushroom-management/"/>
        <id>https://bec-systems.com/blog/0252-mushroom-management/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0252-mushroom-management/">&lt;p&gt;I recall a quote from the book &lt;em&gt;The Soul of a New Machine&lt;&#x2F;em&gt; that describes
“Mushroom Management” and goes something like this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Keep them in the dark, feed them sh**, and watch them grow.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;(This book chronicles the experiences of a computer engineering team racing to
build the next-generation computer at a blistering pace under tremendous
pressure at Data General in the late 1970s.)&lt;&#x2F;p&gt;
&lt;p&gt;Contrast this with &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;cEg8cOx7UZk&quot;&gt;Jensen Huang&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“They never hear me say something to them that is only for them to know. There
is not one piece of information that I secretly tell the staff that I don’t
tell the rest of the company. In that way, our company was designed for
agility, for information to flow as quickly as possible, for people to be
empowered by &lt;strong&gt;what they are able to do, not what they know&lt;&#x2F;strong&gt;. That’s the
architecture of our company.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Where is Data General today? Where is Nvidia? Perhaps this is comparing apples
and oranges though, because as system complexity grows, Huang’s approach is even
more necessary. Systems in the 2020s are many times more complex than those of
the 1970s.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 The BIG Release vs. 🌊 a Continuous flow of Value</title>
        <published>2025-11-05T00:00:00+00:00</published>
        <updated>2025-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0251-the-big-release-vs-a-continuous-flow-of-value/"/>
        <id>https://bec-systems.com/blog/0251-the-big-release-vs-a-continuous-flow-of-value/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0251-the-big-release-vs-a-continuous-flow-of-value/">&lt;p&gt;How do we look at a product release? As a big one-time event, where we spend
heroic efforts to pull it over the finish line? Or as a continuous flow of
high-quality value into the product (even before the customer ever sees it) that
is maintained with every change?&lt;&#x2F;p&gt;
&lt;p&gt;This is a mindset difference that leads to two different approaches:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The BIG v1.0 Release:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Quality is not a priority during development, and gets hammered in with
extreme effort right before the BIG Release.&lt;&#x2F;li&gt;
&lt;li&gt;Tools that make releasing a product easy are not built, rather everything is
done manually before the BIG Release.&lt;&#x2F;li&gt;
&lt;li&gt;Because there is so much work to do for the BIG Release, much of it is not
anticipated so schedules slip.&lt;&#x2F;li&gt;
&lt;li&gt;Issues surface late in the process, which causes further delays.&lt;&#x2F;li&gt;
&lt;li&gt;Stakes are high, pressure mounts, and people become stressed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Continuous flow of Value:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Every pull request (PR) and internal release is treated like an important
customer release.&lt;&#x2F;li&gt;
&lt;li&gt;Tools automatically check quality, eliminating manual verification.&lt;&#x2F;li&gt;
&lt;li&gt;Releases are automated to enable frequent deployments without mistakes.&lt;&#x2F;li&gt;
&lt;li&gt;As a result, the product is always ready to release - internally or to
customers.&lt;&#x2F;li&gt;
&lt;li&gt;Releases happen often (full manufacturing package) because it is easy.&lt;&#x2F;li&gt;
&lt;li&gt;Test fixtures are already done because they are created to test each feature
when the feature was developed.&lt;&#x2F;li&gt;
&lt;li&gt;Prototypes (which are just scaled back manufacturing) are easy to build and
test because a manufacturing release process already exists.&lt;&#x2F;li&gt;
&lt;li&gt;More prototypes get built and more gets learned from actually using the
product.&lt;&#x2F;li&gt;
&lt;li&gt;Issues and manufacturing problems surface early in the design cycle.&lt;&#x2F;li&gt;
&lt;li&gt;Beta releases can be sent to early customers for feedback without hesitation
because the finished features are high quality.&lt;&#x2F;li&gt;
&lt;li&gt;Production release is not a big engineering event, but rather a point where
people start paying for the product.&lt;&#x2F;li&gt;
&lt;li&gt;Schedules are predictable because there is no extra work for production
release, but rather just a focus on the features needed for that incremental
release.&lt;&#x2F;li&gt;
&lt;li&gt;Stress is low, people are happy.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The second scenario is desirable, but what is perhaps not so obvious is the
mindset shift required to get there - a relentless focus on quality throughout
the development process, automating anything done repeatedly, and thorough
testing early in the process. Every internal release, every PR, every day is a
BIG Release.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔀 The Power of Git* workflows</title>
        <published>2025-11-04T00:00:00+00:00</published>
        <updated>2025-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0250-the-genius-of-git-workflows/"/>
        <id>https://bec-systems.com/blog/0250-the-genius-of-git-workflows/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0250-the-genius-of-git-workflows/">&lt;p&gt;Git +
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git hosting platforms&lt;&#x2F;a&gt;
enable &lt;strong&gt;both&lt;&#x2F;strong&gt; local and cloud-based workflows.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Local:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lightning fast access to files - leverage the power of your local computer&lt;&#x2F;li&gt;
&lt;li&gt;Use powerful native tools (editor, e-cad, m-cad, AI agents, command-line
tools, scripts, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Test on local hardware&lt;&#x2F;li&gt;
&lt;li&gt;Work offline&lt;&#x2F;li&gt;
&lt;li&gt;Organize&#x2F;document changes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Cloud:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Collaboration&lt;&#x2F;li&gt;
&lt;li&gt;Distributed development&lt;&#x2F;li&gt;
&lt;li&gt;CI&#x2F;CD&lt;&#x2F;li&gt;
&lt;li&gt;Secure storage&lt;&#x2F;li&gt;
&lt;li&gt;Immutability&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These approaches are not mutually exclusive - both can be leveraged
simultaneously. Software developers take this for granted, but other disciplines
can also benefit from better file management tools. It is beneficial to consider
how both cloud and local domains can be utilized to their fullest potential. In
the end, design assets (data) need to be created, documented, managed, verified,
tested, deployed, secured, and easily &lt;strong&gt;synchronized&lt;&#x2F;strong&gt; between both domains.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✍️ Why writing is important</title>
        <published>2025-11-03T00:00:00+00:00</published>
        <updated>2025-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0249-why-writing-is-important/"/>
        <id>https://bec-systems.com/blog/0249-why-writing-is-important/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0249-why-writing-is-important/">&lt;p&gt;Some people are wildly successful without writing. So, if the goal is only to
make a lot of money or have a lot of power, this advice may not apply.&lt;&#x2F;p&gt;
&lt;p&gt;However, for those who want to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Think better&lt;&#x2F;li&gt;
&lt;li&gt;Scale ideas beyond direct personal contact&lt;&#x2F;li&gt;
&lt;li&gt;Capture and preserve ideas&lt;&#x2F;li&gt;
&lt;li&gt;Grow by building new ideas on old ones&lt;&#x2F;li&gt;
&lt;li&gt;Have influence beyond force and charisma&lt;&#x2F;li&gt;
&lt;li&gt;Effectively
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;good-communication-for-engineers-with-wes-kao-maven-altmba&#x2F;1578&#x2F;2&quot;&gt;manage up&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Not have to redo things over and over&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Then capturing your ideas in a permanent, organized, discoverable place is
essential.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Three levels of workflow</title>
        <published>2025-10-31T00:00:00+00:00</published>
        <updated>2025-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0248-three-levels-of-workflow/"/>
        <id>https://bec-systems.com/blog/0248-three-levels-of-workflow/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0248-three-levels-of-workflow/">&lt;p&gt;There are three levels of workflow:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Personal (what you do to get things done)&lt;&#x2F;li&gt;
&lt;li&gt;Department&#x2F;Discipline (How multiple people who do the same thing get things
done – Example: PCB design)&lt;&#x2F;li&gt;
&lt;li&gt;Cross-functional (How people who do different jobs interact - Example:
Engineering, Support, Manufacturing, Sales, and Marketing)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Effective workflow is increasingly difficult to implement as you go from 1 to 3,
as perspectives, needs, and comfort with various tools differ more. But
cross-functional workflows are also where the &lt;strong&gt;greatest value&lt;&#x2F;strong&gt; lies.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 The benefits of sharing</title>
        <published>2025-10-30T00:00:00+00:00</published>
        <updated>2025-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0247-the-benefits-of-sharing/"/>
        <id>https://bec-systems.com/blog/0247-the-benefits-of-sharing/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0247-the-benefits-of-sharing/">&lt;p&gt;I wrote my first &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;claude-plugins&quot;&gt;Claude plugin&lt;&#x2F;a&gt; that
packages up some commands that I use in about every project I work on. This
plugin allows me to have these commands globally so I don’t have to keep copying
them from project to project.&lt;&#x2F;p&gt;
&lt;p&gt;Although the commands originally worked pretty well, the process of releasing
them publicly made them a lot better. A new &lt;code&gt;implement-tests&lt;&#x2F;code&gt; command was added.
And the commands themselves were cleaned up to be clearer, which will likely
help Claude do a better job.&lt;&#x2F;p&gt;
&lt;p&gt;I am continually amazed by this process. Even if no one else uses or contributes
to this project, I have a better tool for myself, because I shared it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ The new Artisan Age</title>
        <published>2025-10-29T00:00:00+00:00</published>
        <updated>2025-10-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0246-the-new-artisan-age/"/>
        <id>https://bec-systems.com/blog/0246-the-new-artisan-age/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0246-the-new-artisan-age/">&lt;p&gt;We live in a world of powerful tools. Milwaukee battery-powered hand tools,
high-end PCB design suites, cloud platforms, open-source tools, etc. And while
these tools get us a good way toward the goal, they do not do everything.
Additionally, if all you ever use is the mainstream tools, what differentiates
you from anyone else? What prevents others from doing exactly what you are
doing - at a lower cost?&lt;&#x2F;p&gt;
&lt;p&gt;In a previous era, artisan woodworkers built many of their own tools (fixtures,
jigs, squares, planes, storage systems, etc.). As a result, they could highly
optimize for their needs and projects. Tools were not very complex, so it was
possible to make them. Today, things are much more complex. The things we can
buy, or in the case of Open Source use for free, are endless. Many of them are
very useful, but not always exactly what is needed. There is still friction,
waste, manual steps, things that don’t work together, integration pain points,
etc.&lt;&#x2F;p&gt;
&lt;p&gt;In the past, it was very time-consuming to solve integration and automation
problems in complex systems. However, today we are entering a new era where we
can again build tools for complex systems - with AI. AI is excellent at
scripting, automation, testing, configuration, using APIs, generating fixtures,
processing data, etc. Things that would have taken days to implement and figure
out, we can now do in a few minutes. In many ways, we are entering a new artisan
age where we can once again craft custom tools tailored to our specific needs
and workflows. The biggest win with AI is not building your products, but rather
using it to build a custom platform to build your products.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Human Friendly Industrial Device IDs</title>
        <published>2025-10-28T00:00:00+00:00</published>
        <updated>2025-10-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2563/human-friendly-industrial-device-ids/"/>
        <id>https://bec-systems.com/2563/human-friendly-industrial-device-ids/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2563/human-friendly-industrial-device-ids/">&lt;p&gt;Do you deploy 10’s to 1000’s of devices and need to quickly identify them in the field for configuration, maintenance, or troubleshooting? This article explores how this can be made much easier by using device IDs that are easy for humans to process.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;05&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:207px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;In a &lt;a href=&quot;&#x2F;2417&#x2F;survey-of-device-id-mechanisms&#x2F;&quot;&gt;previous article (A Survey of device ID mechanisms)&lt;&#x2F;a&gt;, we explored some of the commonly used options (MAC addresses, UUID, 2D barcodes, etc.). However, most of these are optimized for consumer devices and scenarios where machines process the IDs.&lt;&#x2F;p&gt;
&lt;p&gt;Why are human-friendly IDs important? Consider a few scenarios:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;8 identical temperature sensors are located at various places on a piece of equipment, and we need to identify the location of each one.&lt;&#x2F;li&gt;
&lt;li&gt;3 IO modules are attached to a gateway, and we need to select which module a sensor is connected to when creating a virtual component in a dashboard.&lt;&#x2F;li&gt;
&lt;li&gt;One of the above 3 IO modules in a crowded control panel has failed, and we need to replace it. How do we identify it?&lt;&#x2F;li&gt;
&lt;li&gt;A user calls with a technical support problem on a piece of equipment, and we want to quickly look up the details on the hardware they have (model, version, etc).&lt;&#x2F;li&gt;
&lt;li&gt;We need to list and verify the device serial numbers on a packing list for a shipment to a customer.&lt;&#x2F;li&gt;
&lt;li&gt;Devices are provisioned and configured in the shop for several sites, and during installation, we need to make sure we install the right device in the right location.&lt;&#x2F;li&gt;
&lt;li&gt;A device’s mDNS name defaults to the device’s serial number. Once a device is attached to a network, the user needs to access the Web UI using the address: &lt;code&gt;http:&#x2F;&#x2F;&amp;lt;device id&amp;gt;.local&lt;&#x2F;code&gt;. It is helpful if the ID is simple enough for a user to read from a label and easily type into a browser.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the real world, especially the industrial world, there are many cases where humans need to interact with equipment beyond the initial provisioning.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-15.png&quot; alt=&quot;&quot; style=&quot;width:433px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;the-problem-with-only-qr-codes&quot;&gt;The problem with (only) QR Codes&lt;&#x2F;h2&gt;
&lt;p&gt;QR Codes are increasingly being used to identify devices. We buy a new device, scan the QR code with an app on our phone, and the device gets added to the system – pretty slick! QR Codes are optimized for provisioning, with data flowing in one direction – from the QR code to the system. However, using the QR code to identify a device that is already deployed in the field is more challenging. We need to be able to look at multiple devices in the field and quickly identify them. Also, consider the scenario where you are on the phone supporting a customer – large QR codes are not transmitted over the phone very well. QR codes alone do not solve every problem.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-16.png&quot; alt=&quot;&quot; style=&quot;width:292px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;What works well in the consumer space is not always appropriate for the industrial space. While there are many consumer technologies we can leverage, what Google, Apple, and Amazon are doing is not automatically the best solution for industrial applications. It may be possible to identify a device using a QR code using a complex standard like Matter, but do we have the development resources to make this happen? Do we need the complex security and privacy features in an industrial context? Is there a simpler&#x2F;better solution?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-makes-an-id-easy-for-humans-to-process&quot;&gt;What makes an ID easy for humans to process?&lt;&#x2F;h2&gt;
&lt;p&gt;Many MFA (multi-factor authentication), one-time passwords, and authenticator apps use codes that are composed of 6 digits split into two chunks:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-17.png&quot; alt=&quot;&quot; style=&quot;width:178px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;From experience, we know these numbers are easy to remember and type into a form. Even on our phones, it is often more work to copy and paste than simply look and remember. Why is this? Human short-term memory can typically hold about 7 items at once (plus or minus 2). Chunking these numbers further reduces cognitive load for users. For example, “283-178” is easier to remember than “283178”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;human-friendly-ids-hfid&quot;&gt;Human-friendly IDs (HFID)&lt;&#x2F;h2&gt;
&lt;p&gt;If we start with the format used by authorization codes (&lt;code&gt;XXX-XXX&lt;&#x2F;code&gt;), which is six digits, this gives us one million possibilities (10^6). That is a lot of devices, and may be adequate for some applications.&lt;&#x2F;p&gt;
&lt;p&gt;If we expand this ID to also include capital letters (example: &lt;code&gt;N8H-9MJ&lt;&#x2F;code&gt;), then possible combinations are over 2 billion (36^6).&lt;&#x2F;p&gt;
&lt;p&gt;If we eliminate letters and numbers that are easily confused (&lt;code&gt;0&lt;&#x2F;code&gt;, &lt;code&gt;O&lt;&#x2F;code&gt;, &lt;code&gt;1&lt;&#x2F;code&gt;, &lt;code&gt;I&lt;&#x2F;code&gt;, &lt;code&gt;2&lt;&#x2F;code&gt;, and &lt;code&gt;Z&lt;&#x2F;code&gt;), then reducing the base from 36 to 30 characters (30^6) gives us ~729 million combinations. Randomizing the characters in the ID also helps ensure that the IDs are visually unique and not easily confused with IDs on neighboring devices. We might also want to require a letter and a number in each 3-character chunk to make the ID easily recognizable as an HFID, which would reduce the number of combinations to ~340 million.&lt;&#x2F;p&gt;
&lt;p&gt;340 million is far more than most organizations in the industrial space will ever produce. If there is ever a need for more IDs, then the number of characters could be expanded with a minor loss in usability (example: PU89-V6M2), which gives us 656 billion combinations (30^8).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;managing-device-ids-hfid-org&quot;&gt;Managing Device IDs (hfid.org)&lt;&#x2F;h2&gt;
&lt;p&gt;This scheme does require a central authority to create these IDs – ideally, an API that various manufacturing processes (including subcontractors) can interface with and pull new IDs in real-time. The real value occurs when multiple companies can use the same ID registry, and thus devices from different manufacturers can interoperate. For this, it would be beneficial if there were a vendor-neutral organization that generated these IDs on demand. We created a prototype of a system to do this.&lt;&#x2F;p&gt;
&lt;p&gt;🌐 &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;app.hfid.org&quot;&gt;&lt;strong&gt;https:&#x2F;&#x2F;app.hfid.org&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once your account is approved, you can generate new HFIDs via the website or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;app.hfid.org&#x2F;documentation&quot;&gt;API&lt;&#x2F;a&gt;. Check it out …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-not-both&quot;&gt;Why not both?&lt;&#x2F;h2&gt;
&lt;p&gt;Why not both an HFID and a small QR code containing the HFID on your device? Then it is easy for both humans and machines to process the ID.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;05&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:217px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Human-friendly device IDs are a way to uniquely identify a large number of devices, yet make it easy for humans to quickly and accurately identify devices in the field. Similar to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;tlsl01uxUfE&quot;&gt;Internal Part Numbers designed for humans&lt;&#x2F;a&gt;, systems designed to work well with humans are key to reducing mistakes and improving efficiency.&lt;&#x2F;p&gt;
&lt;p&gt;Even if you are using devices&#x2F;sensors&#x2F;equipment manufactured by others that already have an ID, adding an HFID to any device you deploy allows you to identify it with less effort.&lt;&#x2F;p&gt;
&lt;p&gt;The human eye and brain are remarkable instruments. Implementing IDs that are easy for humans to process has countless benefits as you manufacture, track, deploy, maintain, and service your products, devices, and equipment. Quickly identifying a device is the first step to doing anything with it.&lt;&#x2F;p&gt;
&lt;p&gt;Don’t just use an ID, use an HFID.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏗️ The difference between Product and Platform</title>
        <published>2025-10-27T00:00:00+00:00</published>
        <updated>2025-10-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0245-the-difference-between-product-and-platform/"/>
        <id>https://bec-systems.com/blog/0245-the-difference-between-product-and-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0245-the-difference-between-product-and-platform/">&lt;p&gt;Product is &lt;strong&gt;what&lt;&#x2F;strong&gt; you build.&lt;&#x2F;p&gt;
&lt;p&gt;Platform is &lt;strong&gt;how&lt;&#x2F;strong&gt; you build.&lt;&#x2F;p&gt;
&lt;p&gt;Most people build the first and outsource the second. After all, the product has
the IP—the secret sauce—the valuable part.&lt;&#x2F;p&gt;
&lt;p&gt;However, we
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;shopify-has-a-culture-of-building-internal-software&#x2F;1613&quot;&gt;observe in successful companies&lt;&#x2F;a&gt;
a focus on their internal platform. They build their own tools and workflows
optimized for them. How you build is where the rubber hits the road. If you
don’t master the “how,” getting the “what” done is frustratingly difficult. YOUR
Platform is the engine that keeps product development running smoothly and
allows you to keep ahead of the game. It does not matter so much if someone
steals your ideas because you are already implementing the next ones.&lt;&#x2F;p&gt;
&lt;p&gt;It is relatively easy to copy a physical product. It is nearly impossible to
copy the internal process, culture, workflows, and tools—even if they are freely
shared. Why? Because so few companies have the discipline and will to
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;#platform&quot;&gt;own their platform&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎯 A single source of truth</title>
        <published>2025-10-23T00:00:00+00:00</published>
        <updated>2025-10-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0244-a-single-source-of-truth/"/>
        <id>https://bec-systems.com/blog/0244-a-single-source-of-truth/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0244-a-single-source-of-truth/">&lt;p&gt;An intense discussion about &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;tlsl01uxUfE&quot;&gt;part&#x2F;version numbers&lt;&#x2F;a&gt;
driving application logic surfaced an idea to create a simplified version of the
product metadata that simplified the programming logic. However, this rarely
works out long-term, because several things happen:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The two sets of data must be related and kept in sync.&lt;&#x2F;li&gt;
&lt;li&gt;This approach ends up replicating the first set of data with the second.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Fix the problems with the first set of data, rather than trying to band-aid it
with additional data. Data can be derived by machine, but it should never be
created in parallel. There needs to be a single source of truth. Otherwise
mistakes will happen. More mistakes than just dealing with the first set of
data, no matter how painful.&lt;&#x2F;p&gt;
&lt;p&gt;Manually duplicating data is symptomatic of organizational, not technical
problems. Duplicated data often indicates that organizational silos exist caused
by a lack of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;transparency&lt;&#x2F;li&gt;
&lt;li&gt;collaboration&lt;&#x2F;li&gt;
&lt;li&gt;cross functional teams&lt;&#x2F;li&gt;
&lt;li&gt;common standards&lt;&#x2F;li&gt;
&lt;li&gt;common workflows&lt;&#x2F;li&gt;
&lt;li&gt;common tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Don’t make excuses for these, fix them.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 Scale vs. Value</title>
        <published>2025-10-17T00:00:00+00:00</published>
        <updated>2025-10-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0243-scale-vs-value/"/>
        <id>https://bec-systems.com/blog/0243-scale-vs-value/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0243-scale-vs-value/">&lt;p&gt;As scale increases (# of people, # of technologies, # of products, # of teams,
life cycle of product, experience, amount of knowledge, etc.), what does the
value produced look like?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Metcalfe%27s_law&quot;&gt;Metcalfe’s law&lt;&#x2F;a&gt; states that
the financial value or influence of a telecommunications network is
proportional to the square of the number of connected users of the system.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In communication and economic systems, we often find Metcalfe’s law to be true.
However, personally and organizationally, the results often plateau as
projects&#x2F;systems&#x2F;organizations grow.&lt;&#x2F;p&gt;
&lt;p&gt;Which of the below graphs describes you personally or organizationally? How do
we get from average -&amp;gt; great?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;scale-value-average.png&quot; alt=&quot;average&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;scale-value-good.png&quot; alt=&quot;good&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;scale-value-great.png&quot; alt=&quot;great&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💻 Local First Dev</title>
        <published>2025-10-14T00:00:00+00:00</published>
        <updated>2025-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0242-local-first-dev/"/>
        <id>https://bec-systems.com/blog/0242-local-first-dev/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0242-local-first-dev/">&lt;p&gt;In the last couple decades, we’ve observed the success of SaaS web applications
(Google Docs, Salesforce, Basecamp, Trello, etc.). These applications have
unleashed collaboration using the web platform. Before this, users might have
emailed documents around (many still do this) or shared access to a file-server
or used a terminal server to access common infrastructure. However, nothing can
match the web for low friction&#x2F;cost access.&lt;&#x2F;p&gt;
&lt;p&gt;One of the downsides of SaaS is that users need to re-create the context of
whatever they are doing in the web application (upload files, copy images,
etc.). For many applications, the benefits to collaboration greatly outweighed
the cost of re-creating context. For things like issue tracking, SaaS
applications work well.&lt;&#x2F;p&gt;
&lt;p&gt;However, for more complex workflows (like CI&#x2F;CD&#x2F;PDM&#x2F;PLM), the drawbacks of SaaS
become more apparent because they require much more context. Some products,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;jon-hirschtick-founder-of-solidworks-and-onshape&#x2F;1575&quot;&gt;like Onshape&lt;&#x2F;a&gt;,
solve this problem by moving everything to the cloud. This works great for pure
mechanical products, but what about electrical and software? Should these all
operate in their own silos?&lt;&#x2F;p&gt;
&lt;p&gt;A more compelling vision is a mixture of SaaS and local tooling. Examples
include:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;claude-claude-code&#x2F;1534&quot;&gt;Claude Code&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;: while
using AI in web sites is very useful, running AI locally in your terminal is a
huge step-level improvement for actually doing work (not just answering
questions).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;modelcontextprotocol.io&#x2F;&quot;&gt;Model Context Protocol (MCP)&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;: allows AI
to connect to local applications and data.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git hosting apps&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;:
Gitea&#x2F;Github&#x2F;Gitlab have demonstrated amazing utility for software developers by
mixing local tooling (Git, Actions, etc.) with an accessible cloud web
application.&lt;&#x2F;p&gt;
&lt;p&gt;Pushing data to the edge is how to scale, and files are the obvious way to do
this. While this has
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0192-why-gui-development-tools-don-t-scale&#x2F;&quot;&gt;always been true&lt;&#x2F;a&gt;,
the rise of AI is making this fact crystal clear.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💬 The importance of effective communication</title>
        <published>2025-10-13T00:00:00+00:00</published>
        <updated>2025-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0241-the-importance-of-effective-communication/"/>
        <id>https://bec-systems.com/blog/0241-the-importance-of-effective-communication/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0241-the-importance-of-effective-communication/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0205-effective-communication-written&#x2F;&quot;&gt;Recently&lt;&#x2F;a&gt;,
effective communication has been discussed. But let’s step back – why is
communication so important? As developers, isn’t coding what we do? Think for a
minute – how much time gets spent coding&#x2F;designing vs. everything else? For
most, it is probably too little time on producing and way too much on everything
else. Becoming a more effective communicator is the one way to spend less time
on “everything else” leaving more time to produce.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧠 Context is everything</title>
        <published>2025-10-10T00:00:00+00:00</published>
        <updated>2025-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0240-context-is-everything/"/>
        <id>https://bec-systems.com/blog/0240-context-is-everything/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0240-context-is-everything/">&lt;p&gt;In conversation, I find myself saying: “what is the context of your comment?” At
times we find ourselves responding before we really understand something.&lt;&#x2F;p&gt;
&lt;p&gt;AI does the same thing – it just spouts off, even if it does not understand
your context.&lt;&#x2F;p&gt;
&lt;p&gt;This is one reason local agents like Claude Code work so well, vs AI in a web
browser. Local agents at least have the context of your code and local files.
However, it still does not have access to your complete domain context – that
is your part.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💡 Reflections from AI-coding a 10,000 line app</title>
        <published>2025-10-08T00:00:00+00:00</published>
        <updated>2025-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0239-reflections-from-ai-coding-a-10-000-line-app/"/>
        <id>https://bec-systems.com/blog/0239-reflections-from-ai-coding-a-10-000-line-app/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0239-reflections-from-ai-coding-a-10-000-line-app/">&lt;p&gt;Lessons from AI-coding a 10,000 line app&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;brun&quot;&gt;BRun&lt;&#x2F;a&gt; is getting usable. Claude Code wrote
almost all of it using
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0218-close-the-loop-with-ai&#x2F;&quot;&gt;Doc-driven development&lt;&#x2F;a&gt;
(manually write&#x2F;update the docs, and have Claude write the code).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Some thoughts:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Claude is fast – there is no way I could have written this app manually in a
day or so.&lt;&#x2F;li&gt;
&lt;li&gt;Large changes are easy with AI.&lt;&#x2F;li&gt;
&lt;li&gt;Keeping docs up to date is easy.&lt;&#x2F;li&gt;
&lt;li&gt;Having AI do the coding freed up more time to think about the app user
interface, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Claude is a nice partner to bounce ideas off of.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Some things to watch out for:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Look out for duplicated&#x2F;unnecessary code. There were multiple cases where
Claude was calling the same function multiple times.&lt;&#x2F;li&gt;
&lt;li&gt;Refactoring is not always complete. If things get restructured, check that
everything got cleaned up.&lt;&#x2F;li&gt;
&lt;li&gt;Check the tests – Claude really goes crazy generating tests. A lot of work
remains on this repo reviewing and cleaning up tests.&lt;&#x2F;li&gt;
&lt;li&gt;Claude often tends toward complex approaches and a lot more code than needed
– like many junior devs. Close monitoring is needed to ensure the
architecture takes the simple path.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0230-code-is-a-liability-not-an-asset&#x2F;&quot;&gt;Code is a liability, not an asset&lt;&#x2F;a&gt;
– even with AI.&lt;&#x2F;li&gt;
&lt;li&gt;Docs updated by Claude tend to be overly verbose. I was continually trimming
them down to remove duplicated&#x2F;unnecessary content.&lt;&#x2F;li&gt;
&lt;li&gt;Critical things like life-cycle and state management often get overlooked.&lt;&#x2F;li&gt;
&lt;li&gt;Race conditions are also easy to miss in AI-generated code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the end, this project went well, but it still needed expert guidance at
times. Perhaps some of the above could have been improved with more specific
rules. Like many things, the greatest strength is also the greatest weakness.
Claude is really good at generating code – so good that it tends to generate
way too much at times. The hardest part of an app like this is figuring out what
it should do, how it should be configured, what the UI looks like, and debugging
problems when it does not work. This takes experience and is still a lot of work
to get right.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📏 Less code is not the ultimate goal</title>
        <published>2025-10-03T00:00:00+00:00</published>
        <updated>2025-10-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0238-less-code-is-not-the-ultimate-goal/"/>
        <id>https://bec-systems.com/blog/0238-less-code-is-not-the-ultimate-goal/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0238-less-code-is-not-the-ultimate-goal/">&lt;p&gt;Less code is not the ultimate goal&lt;&#x2F;p&gt;
&lt;p&gt;Consider the following
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ioccc.org&#x2F;2020&#x2F;burton&#x2F;index.html&quot;&gt;byte to binary C program&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;int main(int b,char**i){long long n=B,a=I^n,r=(a&#x2F;b&amp;amp;a)&amp;gt;&amp;gt;4,y=atoi(*++i),_=(((a^n&#x2F;b)*(y&amp;gt;&amp;gt;T)|
y&amp;gt;&amp;gt;S)&amp;amp;r)|(a^r);printf(&amp;quot;%.8s\n&amp;quot;,(char*)&amp;amp;_);}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unless you are trying to win the International Obfuscated C Code Contest, this
is not good code. In spite of what I’ve
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0230-code-is-a-liability-not-an-asset&#x2F;&quot;&gt;said before&lt;&#x2F;a&gt;,
less code is not always better. The highest goal is readable maintainable code.
Sometimes we have to write more code to have readable code. An example is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0236-align-the-happy&#x2F;&quot;&gt;aligning the happy path&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Less code is more about not implementing unneeded features, cleaning up dead
code, refactoring to simplify and eliminate duplicated code, etc. The goal of
less code should never sacrifice readability or maintainability.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😊 Other ways to align the happy path</title>
        <published>2025-10-01T00:00:00+00:00</published>
        <updated>2025-10-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0237-other-ways-to-align-the-happy-path/"/>
        <id>https://bec-systems.com/blog/0237-other-ways-to-align-the-happy-path/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0237-other-ways-to-align-the-happy-path/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0236-align-the-happy&#x2F;&quot;&gt;Yesterday&lt;&#x2F;a&gt;, we discussed
aligning the happy path in code. Are there other ways to align the “happy path”?
&lt;em&gt;(The happy path is the desired path where things are functioning as expected.)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some thoughts:&lt;&#x2F;p&gt;
&lt;p&gt;Focus on your productive people - as a manager focus your efforts on making life
better for the productive 95% of your team, rather than trying to fix the
unproductive 5% who probably cannot be helped anyway. At least make your efforts
proportional. We should be willing to help people who sincerely want help, but
trying to help those who do not want help drains our soul.&lt;&#x2F;p&gt;
&lt;p&gt;Processes should focus on making the primary work go faster and easier. Sure,
problems must be addressed, but returns are higher on improving the work
desired, vs. knocking down problems. If the former is done better, less time
will be spent on the latter.&lt;&#x2F;p&gt;
&lt;p&gt;Proactively write tests to ensure the system is doing what you want it to do,
rather than wait for bugs to appear and then write tests to cover those.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, if energy is proactively focused on what is wanted to happen, a lot
less time will be spent battling things not wanted.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😊 Align the &quot;happy path&quot; in your code</title>
        <published>2025-09-30T00:00:00+00:00</published>
        <updated>2025-09-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0236-align-the-happy/"/>
        <id>https://bec-systems.com/blog/0236-align-the-happy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0236-align-the-happy/">&lt;p&gt;An idiom that I learned in the Go community is to align the happy path. An
example in C below:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;happy-path-not-aligned&quot;&gt;happy path not aligned&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;int process_file(const char* filename) {
    FILE* f = fopen(filename, &amp;quot;r&amp;quot;);
    if (f != NULL) {
        char buffer[100];
        if (fgets(buffer, sizeof(buffer), f) != NULL) {
            &#x2F;&#x2F; process buffer
            fclose(f);
            return 0; &#x2F;&#x2F; success
        } else {
            fclose(f);
            return -2; &#x2F;&#x2F; error: unable to read
        }
    } else {
        return -1; &#x2F;&#x2F; error: unable to open
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;happy-path-aligned&quot;&gt;happy path aligned&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;int process_file(const char* filename) {
    FILE* f = fopen(filename, &amp;quot;r&amp;quot;);
    if (f == NULL)
        return -1; &#x2F;&#x2F; error: unable to open

    char buffer[100];
    if (fgets(buffer, sizeof(buffer), f) == NULL) {
        fclose(f);
        return -2; &#x2F;&#x2F; error: unable to read
    }

    &#x2F;&#x2F; process buffer

    fclose(f);
    return 0; &#x2F;&#x2F; success
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the first example, it is more difficult to follow the logic due to nested if
statements. In the second example, it is easy to scan down through the code
aligned to the left and sequentially see what it is supposed to do.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔓 You should not be needed</title>
        <published>2025-09-29T00:00:00+00:00</published>
        <updated>2025-09-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0235-you-should-not-be-needed/"/>
        <id>https://bec-systems.com/blog/0235-you-should-not-be-needed/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0235-you-should-not-be-needed/">&lt;p&gt;An effective process, team, or organization should be able to continue on if any
individual steps away for a bit, or forever. But, most people are insecure and
like to be needed, so subconsciously structure things to require them to be
present for things to proceed – the gatekeeper or authoritarian mindset.&lt;&#x2F;p&gt;
&lt;p&gt;A few ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nathanbarry.com&#x2F;89697-reasons-to-teach&#x2F;&quot;&gt;Share everything you know&lt;&#x2F;a&gt;
with the widest possible audience.&lt;&#x2F;li&gt;
&lt;li&gt;Document &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;#why&quot;&gt;why&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Automate tedious processes so anyone can execute them. This also serves as
good documentation.&lt;&#x2F;li&gt;
&lt;li&gt;Encourage others to do things you do.&lt;&#x2F;li&gt;
&lt;li&gt;Prefer transparency for accountability rather than oversight or status
reports.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Creating a process or culture that can function just fine without a single point
of dependency makes that person more valuable than ever, and frees them up to do
other higher-value things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚧 Three things that hinder product development</title>
        <published>2025-09-24T00:00:00+00:00</published>
        <updated>2025-09-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0234-three-things-that-hinder-product-development/"/>
        <id>https://bec-systems.com/blog/0234-three-things-that-hinder-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0234-three-things-that-hinder-product-development/">&lt;ol&gt;
&lt;li&gt;Not using new tech when applicable.&lt;&#x2F;li&gt;
&lt;li&gt;Doing the same work over and over again instead of automating.&lt;&#x2F;li&gt;
&lt;li&gt;Lack of collaboration.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚙️ Three aspects of product development</title>
        <published>2025-09-23T00:00:00+00:00</published>
        <updated>2025-09-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0233-three-aspects-of-product-development/"/>
        <id>https://bec-systems.com/blog/0233-three-aspects-of-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0233-three-aspects-of-product-development/">&lt;ol&gt;
&lt;li&gt;Finding and leveraging existing technology.&lt;&#x2F;li&gt;
&lt;li&gt;Developing some of your own technology.&lt;&#x2F;li&gt;
&lt;li&gt;Mixing it together.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;All three are necessary.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Technical debt compounds with you doing nothing</title>
        <published>2025-09-22T00:00:00+00:00</published>
        <updated>2025-09-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0232-technical-debt-compounds-with-you-doing-nothing/"/>
        <id>https://bec-systems.com/blog/0232-technical-debt-compounds-with-you-doing-nothing/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0232-technical-debt-compounds-with-you-doing-nothing/">&lt;p&gt;Technical debt is like any other kind of debt – it accrues when nothing is
done. This is perhaps the most insidious aspect of debt.&lt;&#x2F;p&gt;
&lt;p&gt;How does technical debt work? Mainly that software (and technology in general)
moves on (especially OSS), and we do not keep up.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“It works, why do we need to update? That just introduces risk.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;But the longer we put this off, it becomes exponentially harder to ever catch up
– just like compound interest on financial debt never receiving payments.&lt;&#x2F;p&gt;
&lt;p&gt;The other aspect of doing nothing is that infrastructure rots – the tools,
automation, testing, and know-how that even allow making changes and improve
things. So when the gap is huge and there is no infrastructure (way to close the
gap), it is nearly impossible, so we declare bankruptcy and start over.&lt;&#x2F;p&gt;
&lt;p&gt;There is another path: keep up-to-date. This forces the infrastructure to stay
fresh. Iterations expose areas that can be automated and improved. Investing in
YOUR platform compounds benefits over time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📚 Without docs</title>
        <published>2025-09-12T00:00:00+00:00</published>
        <updated>2025-09-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0231-without-docs/"/>
        <id>https://bec-systems.com/blog/0231-without-docs/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0231-without-docs/">&lt;p&gt;Design files (mechanical, electrical, or software) contain the technical details
that allow us to manufacture something in the moment, but they often don’t
contain the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0223-document-why-not-how&#x2F;&quot;&gt;“why”&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Why is this mechanical feature present?&lt;&#x2F;li&gt;
&lt;li&gt;Why is this circuit necessary?&lt;&#x2F;li&gt;
&lt;li&gt;Why is the code structured this way?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Most designs exist this way – without adequate documentation. What happens two
years later when something quits working? What happens when a new feature needs
added? What happens when someone leaves?&lt;&#x2F;p&gt;
&lt;p&gt;World-class engineering requires world-class documentation. There is no other
way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Code is a liability, not an asset</title>
        <published>2025-09-11T00:00:00+00:00</published>
        <updated>2025-09-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0230-code-is-a-liability-not-an-asset/"/>
        <id>https://bec-systems.com/blog/0230-code-is-a-liability-not-an-asset/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0230-code-is-a-liability-not-an-asset/">&lt;p&gt;A wise developer
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;stettix&#x2F;5bb2d99e50fdbbd15dd9622837d14e2b&quot;&gt;once said&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code is a liability, not an asset. Aim to have as little of it as possible.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is perhaps the #1 rule for clean code. Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Don’t implement “just in case” features. Remember
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0229-yagni&#x2F;&quot;&gt;YAGNI&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0087-abstractions-and-platforms&#x2F;&quot;&gt;Premature abstractions&lt;&#x2F;a&gt;
often do more harm than good.&lt;&#x2F;li&gt;
&lt;li&gt;Premature optimization is the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0078-architecture-vs-optimization&#x2F;&quot;&gt;root of all evil&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;2432&#x2F;struggling-to-scale-your-iot-system-simplify-your-data&#x2F;&quot;&gt;Simple data structures scale&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0034-seeing-patterns&#x2F;&quot;&gt;Find patterns&lt;&#x2F;a&gt; and
refactor often.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Just-in-case development (implementing stuff not needed right now) is a powerful
force, especially with less experienced developers who have not spent
significant time maintaining software.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Understand the problem before starting implementation.&lt;&#x2F;li&gt;
&lt;li&gt;If at all possible, reproduce the bug before trying to fix it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✂️ YAGNI</title>
        <published>2025-09-10T00:00:00+00:00</published>
        <updated>2025-09-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0229-yagni/"/>
        <id>https://bec-systems.com/blog/0229-yagni/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0229-yagni/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;You_aren&amp;#x27;t_gonna_need_it&quot;&gt;YAGNI&lt;&#x2F;a&gt; - “You ain’t
gonna need it!”&lt;&#x2F;p&gt;
&lt;p&gt;If you don’t need it now, the chances you’ll need it in the future are small, or
at least not the current implementation. Do the simplest thing that works now. Get
feedback. Repeat.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0178-how-to-define-an-iteration&#x2F;&quot;&gt;Iterations&lt;&#x2F;a&gt; are
the key – get better at doing iterations faster (including testing, and
feedback), not implementing more stuff now.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🐛Kernighan&#x27;s Law</title>
        <published>2025-09-09T00:00:00+00:00</published>
        <updated>2025-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0228-kernighan-s-law/"/>
        <id>https://bec-systems.com/blog/0228-kernighan-s-law/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0228-kernighan-s-law/">&lt;p&gt;&lt;strong&gt;Kernighan’s Law:&lt;&#x2F;strong&gt; &lt;em&gt;Debugging is twice as hard as writing the code in the
first place. Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Cliff’s Law:&lt;&#x2F;strong&gt; &lt;em&gt;In three months, it will be three times harder to read the
code you just wrote than writing the code in the first place. With AI, add a 10x
factor.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Maintaining code over a product lifecycle is many times harder than the initial
implementation. With AI,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0218-close-the-loop-with-ai&#x2F;&quot;&gt;doc&lt;&#x2F;a&gt; or
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;github&#x2F;spec-kit&quot;&gt;spec&lt;&#x2F;a&gt; driven development is critical.
Otherwise, you will bury yourself in technical debt. Make it easy on others and
your future self.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌀 Complex systems are hard to predict</title>
        <published>2025-09-08T00:00:00+00:00</published>
        <updated>2025-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0227-complex-systems-are-hard-to-predict/"/>
        <id>https://bec-systems.com/blog/0227-complex-systems-are-hard-to-predict/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0227-complex-systems-are-hard-to-predict/">&lt;p&gt;My wife makes sourdough, which is a multi-day process and at times
unpredictable. Recently, the current batch was a little sluggish and not
expanding like it should, so she “fed” it and left it on the counter. It took
off during the night and was all over the counter in the morning.&lt;&#x2F;p&gt;
&lt;p&gt;Sourdough is a complex living system. Because of this, sourdough is difficult to
predict 100% of the time. As computer systems become more complex, they take on
some of the same characteristics of living systems. You can’t completely predict
everything. What worked yesterday may not work today, due to various external
factors that cannot be controlled or fully understood. Especially with networked
systems – we cannot control everything else on the network, or involved with
the network. We cannot control what new feature customers are going to ask for
that might require us to update dependencies. We can’t predict what new edge
case will trigger a bug we have not seen before.&lt;&#x2F;p&gt;
&lt;p&gt;The best we can do is keep tools and processes flexible, up-to-date, and as
automated as possible (YOUR Platform). This enhances the ability to adapt to the
external forces that cannot be controlled.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📊 Simple data formats + powerful tools scale</title>
        <published>2025-09-04T00:00:00+00:00</published>
        <updated>2025-09-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0226-simple-formats-powerful-tools/"/>
        <id>https://bec-systems.com/blog/0226-simple-formats-powerful-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0226-simple-formats-powerful-tools/">&lt;p&gt;There is an ongoing shift in data analysis tools. Another example is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;datavzrd.github.io&#x2F;&quot;&gt;datavzrd&lt;&#x2F;a&gt;. datavzrd is a zero&#x2F;low-code,
interactive, visual, server-free, browser-based reporting tool for tabular
datasets.&lt;&#x2F;p&gt;
&lt;p&gt;The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;journals.plos.org&#x2F;plosone&#x2F;article?id=10.1371&#x2F;journal.pone.0323079&quot;&gt;paper&lt;&#x2F;a&gt;
makes an interesting statement:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Most spreadsheet applications, including Excel, lack the capability to quickly
and easily visualize different columns of a dataset. They also &lt;strong&gt;do not
support reproducibility of results for similar datasets without repeating the
work&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This last point is key. For example, if data needs monthly review, tools like
this make a lot of sense. Complete automation becomes possible. Manual
spreadsheet work every month becomes unnecessary, eliminating tedious and
error-prone processes.&lt;&#x2F;p&gt;
&lt;p&gt;This is another example of the trend toward
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0191-text-based-formats-and-command-line-tools-are-the-future&#x2F;&quot;&gt;simple data formats&lt;&#x2F;a&gt;
and flexible tools.&lt;&#x2F;p&gt;
&lt;p&gt;YAML, CSV, and Markdown are the file formats of the future.&lt;&#x2F;p&gt;
&lt;p&gt;Simple data formats + powerful tools is the formula that scales.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📚 Documentation never has to go out of date again</title>
        <published>2025-09-03T00:00:00+00:00</published>
        <updated>2025-09-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0225-documentation-never-has-to-go-out-of-date-again/"/>
        <id>https://bec-systems.com/blog/0225-documentation-never-has-to-go-out-of-date-again/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0225-documentation-never-has-to-go-out-of-date-again/">&lt;p&gt;AI is really good at updating documentation after implementation. While I
strongly advocate
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0218-close-the-loop-with-ai&#x2F;&quot;&gt;writing the documentation to drive AI&lt;&#x2F;a&gt;,
inevitably, the implementation takes some unanticipated turns, so making sure
everything is in sync after implementation is a good task for AI.&lt;&#x2F;p&gt;
&lt;p&gt;Are the docs up to date? With Claude Code (or something similar), there is
really no excuse.&lt;&#x2F;p&gt;
&lt;p&gt;However, it helps to standardize on the format the AI knows best:
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;#markdown&quot;&gt;Markdown&lt;&#x2F;a&gt;, and it helps a lot to
keep the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0224-keep-documentation-close-to-the-design-code&#x2F;&quot;&gt;docs close to the design&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📚 Keep documentation close to the design&#x2F;code</title>
        <published>2025-09-02T00:00:00+00:00</published>
        <updated>2025-09-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0224-keep-documentation-close-to-the-design-code/"/>
        <id>https://bec-systems.com/blog/0224-keep-documentation-close-to-the-design-code/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0224-keep-documentation-close-to-the-design-code/">&lt;p&gt;I find it works best to keep documentation as close to the code or design files
as possible. There are several benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can update, commit, and review documentation as part of the standard
working process (pull requests, CI, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;You can use tools you are already using (like your favorite editor)&lt;&#x2F;li&gt;
&lt;li&gt;It encourages the use of Markdown (the format AI works with)&lt;&#x2F;li&gt;
&lt;li&gt;Claude Code, which you run from your working directory, has access to it. This
has always been important, but with AI tools, it is even more important—more
on that in future.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 Document &quot;why&quot; not &quot;how&quot;</title>
        <published>2025-08-29T00:00:00+00:00</published>
        <updated>2025-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0223-document-why-not-how/"/>
        <id>https://bec-systems.com/blog/0223-document-why-not-how/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0223-document-why-not-how/">&lt;p&gt;Be kind to others (and your future self) and document why you did something.&lt;&#x2F;p&gt;
&lt;p&gt;AI is pretty good at generating the “how” any time you need it, but only you
know the “why” because you have that context.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Closed-loop engineering</title>
        <published>2025-08-28T00:00:00+00:00</published>
        <updated>2025-08-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0222-closed-loop-engineering/"/>
        <id>https://bec-systems.com/blog/0222-closed-loop-engineering/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0222-closed-loop-engineering/">&lt;p&gt;What are some ways we can close the loop in engineering efforts?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Systematic testing&lt;&#x2F;li&gt;
&lt;li&gt;User feedback&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These ensure whatever we build &lt;strong&gt;works&lt;&#x2F;strong&gt; and is &lt;strong&gt;useful&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚴 The power of movement</title>
        <published>2025-08-27T00:00:00+00:00</published>
        <updated>2025-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0221-the-power-of-movement/"/>
        <id>https://bec-systems.com/blog/0221-the-power-of-movement/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0221-the-power-of-movement/">&lt;p&gt;Rod’s thoughts on
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rodaparicio.kit.com&#x2F;posts&#x2F;riding-a-bike&quot;&gt;Riding a Bike&lt;&#x2F;a&gt; are thought
provoking.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;… A decision that might be bad. Yet, with it, you can steer. Just like
riding a bike. If it’s standing with no movement, you can direct the handle
and still be where you are. It’s when you’re moving on the bike that you give
direction.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I’ve often experienced this in software development where I don’t really know
how I’m going to solve a problem until I start coding, and then things start to
emerge. The same happens with
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;writing&#x2F;&quot;&gt;writing&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;drawing&#x2F;&quot;&gt;sketching&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There is value in up-front planning, but there is power in movement, especially
when you &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;iteration&#x2F;&quot;&gt;iterate&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;closed-loop&#x2F;&quot;&gt;close-the-loop&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Closed-loop humans</title>
        <published>2025-08-26T00:00:00+00:00</published>
        <updated>2025-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0220-closed-loop-humans/"/>
        <id>https://bec-systems.com/blog/0220-closed-loop-humans/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0220-closed-loop-humans/">&lt;p&gt;What are some ways we as humans can close the loop?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Listen&lt;&#x2F;li&gt;
&lt;li&gt;Reflect&lt;&#x2F;li&gt;
&lt;li&gt;Write&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Without these, we operate in a largely open-loop mode without the feedback we
need to improve or correct our course.&lt;&#x2F;p&gt;
&lt;p&gt;Action bias is good, but it helps to know we are doing the right things and
going in the right direction.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Look for closed loops</title>
        <published>2025-08-25T00:00:00+00:00</published>
        <updated>2025-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0219-look-for-closed-loops/"/>
        <id>https://bec-systems.com/blog/0219-look-for-closed-loops/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0219-look-for-closed-loops/">&lt;p&gt;Closed loop systems are stable. Why? Because they learn and self-correct.&lt;&#x2F;p&gt;
&lt;p&gt;In any system, process, person, or organization, look for closed loops. If
something is not working, chances are there is an open loop.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Close the loop with AI</title>
        <published>2025-08-22T00:00:00+00:00</published>
        <updated>2025-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0218-close-the-loop-with-ai/"/>
        <id>https://bec-systems.com/blog/0218-close-the-loop-with-ai/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0218-close-the-loop-with-ai/">&lt;p&gt;There is a fascinating statement in a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;state-of-ai-in-business-2025-report&#x2F;1584&quot;&gt;recent MIT study&lt;&#x2F;a&gt;
that claims 95% of organizations are getting zero return from GenAI investments.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The core barrier to scaling is not infrastructure, regulation, or talent. It
is learning. Most GenAI systems do not retain feedback, adapt to context, or
improve over time.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;AI proves useful to software developers, perhaps because so much context is
available, giving it a better starting point than in most other industries.&lt;&#x2F;p&gt;
&lt;p&gt;However, I think we can still do better by closing the loop. The below workflow
is currently working well for me:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;ai-closed-loop-workflow.png&quot; alt=&quot;image.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Closing the loop means retaining and re-using what you have learned.
Interestingly, it does not really matter if humans or AI are doing the work—the
same process works well with both.&lt;&#x2F;p&gt;
&lt;p&gt;Notice the absence of AI prompts – while an AI tool may remember prompts for a
session, they are lost on the next. They are “open-loop”.&lt;&#x2F;p&gt;
&lt;p&gt;Code is not the most valuable asset you own, but rather the ability to generate,
maintain, and improve it—the process. It is kind of like personal wealth and
skills. Even if we lose the first, we can always generate more with the second.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💰 Ways to reduce your AI costs</title>
        <published>2025-08-21T00:00:00+00:00</published>
        <updated>2025-08-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0217-ways-to-reduce-your-ai-costs/"/>
        <id>https://bec-systems.com/blog/0217-ways-to-reduce-your-ai-costs/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0217-ways-to-reduce-your-ai-costs/">&lt;p&gt;AI is not free, as there are significant costs associated with training and
hosting modern AI models. Some ideas on how to reduce costs with tools like
Claude Code:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If you do something that is somewhat repetitive, have AI generate scripts or
programs that do the work instead of using AI directly. AI excels at creating
automation tools.&lt;&#x2F;li&gt;
&lt;li&gt;Capture context. Instead of relying solely on prompts, update documentation
and have AI implement the doc changes. This approach captures a lot of context
instead of losing context in prompts.&lt;&#x2F;li&gt;
&lt;li&gt;Start with more complete and accurate descriptions of what needs to be done.&lt;&#x2F;li&gt;
&lt;li&gt;Use cheaper models. In my experience, Claude Sonnet performs just as well as
Claude Opus for most tasks I need to complete. Sonnet is 1&#x2F;5 the cost and is
generally faster.&lt;&#x2F;li&gt;
&lt;li&gt;If the agent is spinning its wheels, stop it, provide more details, and
resume.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💰 What is the cheapest PDM tool out there?</title>
        <published>2025-08-19T00:00:00+00:00</published>
        <updated>2025-08-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0216-what-is-the-cheapest-pdm-tool-out-there/"/>
        <id>https://bec-systems.com/blog/0216-what-is-the-cheapest-pdm-tool-out-there/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0216-what-is-the-cheapest-pdm-tool-out-there/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Product_data_management&quot;&gt;Product Data Management (PDM)&lt;&#x2F;a&gt;
is how you manage and publish your product data. The goal is to ensure all the
stakeholders share a common understanding, confusion is minimized, and quality
is maintained.&lt;&#x2F;p&gt;
&lt;p&gt;The simplest PDM system is to put a bunch of files on a fileserver and talk
about them in meetings, emails, or other messages. This is a start, but it is
error-prone and does not scale.&lt;&#x2F;p&gt;
&lt;p&gt;There are many commercial PDM tools available. CAD systems,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;jon-hirschtick-founder-of-solidworks-and-onshape&#x2F;1575&quot;&gt;like Onshape&lt;&#x2F;a&gt;,
provide PDM features. Software developers have been doing PDM to various degrees
for decades using open-source tools. You have SCCS (1972), RCS (1982), CVS
(1986), SVN (2000), and Git (2005).&lt;&#x2F;p&gt;
&lt;p&gt;Git and its various
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;hosting platforms&lt;&#x2F;a&gt;
support a number of the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0214-git-solves-the-problem-of-managing-files&#x2F;&quot;&gt;features&lt;&#x2F;a&gt;
needed for PDM. The cost is minimal and you probably already have people on
staff who are experts at using it. For small teams, Git may just be the PDM
solution you need. However, there is a learning curve, and some additional
tooling may be required to make it accessible—more on that in the future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🗂️ Git has an unfortunate name</title>
        <published>2025-08-18T00:00:00+00:00</published>
        <updated>2025-08-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0215-git-has-an-unfortunate-name/"/>
        <id>https://bec-systems.com/blog/0215-git-has-an-unfortunate-name/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0215-git-has-an-unfortunate-name/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Git&quot;&gt;Git&lt;&#x2F;a&gt;, which was created 20 years, and
various
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;hosting platforms&lt;&#x2F;a&gt;,
has &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;723&#x2F;why-git&#x2F;&quot;&gt;revolutionized&lt;&#x2F;a&gt; software development
workflow and collaboration. The name Git was chosen by its creator, Linus
Torvalds, and has a humorous backstory rooted in both practicality and
world-class trolling. In British slang, “git” is an insult meaning
an unpleasant or silly person, which Torvalds acknowledged with characteristic
Finnish bluntness: “I’m an egotistical &lt;strong&gt;___&lt;&#x2F;strong&gt;, and I name all my projects
after myself. First Linux, now Git.”&lt;&#x2F;p&gt;
&lt;p&gt;Most of us software developers, especially in OSS culture, appreciate a little
humor and self-deprecation (it’s basically a job requirement at this point).
However, those from other disciplines seem to have an inexplicable aversion to
anything with the word “git” in it. Perhaps this is understandable – why would
I ever use a tool that literally calls me stupid in the name? That must mean I’m
stupid if I use it, right? This appears to be a subconscious psychological
defense mechanism that is surprisingly hard to overcome. It unfolds something
like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Developer (D)&lt;&#x2F;strong&gt;: Hey, why don’t we use
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git*&lt;&#x2F;a&gt;
for this project? It handles all our
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0214-git-solves-the-problem-of-managing-files&#x2F;&quot;&gt;file management problems&lt;&#x2F;a&gt;
with some project management tools thrown in.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Project Manager (P)&lt;&#x2F;strong&gt;: Great idea! (Famous last words)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;: Can you comment on that “Git” PR I just posted?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;&#x2F;strong&gt;: Sure.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;deafening silence&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;: Can you push the new product specification you wrote to the “Git” repo
in Markdown so we can track and review changes?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;&#x2F;strong&gt;: Sure! (Proceeds to email a Word doc like it’s still 2003)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;developer dies a little inside&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;: Can you test the new release in “Git”? (link to Git* release).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;&#x2F;strong&gt;: (a little while later) Can you just email the files to Nick? (Git? What
Git?)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;: &lt;code&gt;&amp;lt;internal screaming intensifies&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;: (at the weekly status meeting) Why am I the only one tracking my tasks
in “GitHub” issues?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;P:&lt;&#x2F;strong&gt; Good question, we should all do that. (Immediately forgets and goes
back to sticky notes)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;the sound of one developer crying&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D:&lt;&#x2F;strong&gt; Why don’t people use “Git” when it has most of the file management,
collaboration, and PM tools we need?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;P:&lt;&#x2F;strong&gt; It’s too hard. (Says the person who maintains a 47-tab Gantt chart in
Excel)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D:&lt;&#x2F;strong&gt; It’s a lot simpler than a mega Gantt chart in Excel, or a 3D model in
SolidWorks.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;P:&lt;&#x2F;strong&gt; True. (Goes back to Excel anyway)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;the void stares back&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The only rational conclusion I can come up with is that the word “Git” somehow
triggers a Pavlovian response in most people’s brains that makes them physically
unable to click on anything Git-related. It’s like some kind of linguistic
kryptonite. Only a minority of battle-hardened software nerds, especially those
who’ve been sufficiently traumatized by OSS projects, have managed to overcome
the existential crisis of using a tool that openly mocks them.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📁 Git* solves the problem of managing files</title>
        <published>2025-08-15T00:00:00+00:00</published>
        <updated>2025-08-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0214-git-solves-the-problem-of-managing-files/"/>
        <id>https://bec-systems.com/blog/0214-git-solves-the-problem-of-managing-files/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0214-git-solves-the-problem-of-managing-files/">&lt;p&gt;The thing you get with
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git*&lt;&#x2F;a&gt;
is a sane way to manage files:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;organization&lt;&#x2F;strong&gt; (team&#x2F;repo&#x2F;directories)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;documentation&lt;&#x2F;strong&gt; (excellent support for Markdown)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;efficient navigation&lt;&#x2F;strong&gt; (links in READMEs and other markdown files)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;history&lt;&#x2F;strong&gt; (who changed what when)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;collaboration&lt;&#x2F;strong&gt; (issues, pull requests)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;distributed&lt;&#x2F;strong&gt; (anyone can work anywhere)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;automation&lt;&#x2F;strong&gt; (continuous integreation (CI), continuous deployment (CD),
hooks, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;reviews&lt;&#x2F;strong&gt; (PRs)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;workflow&lt;&#x2F;strong&gt; (enforces workflow such as requiring PRs, approvals, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;versions&lt;&#x2F;strong&gt; (feature and maintenance branches)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;releases&lt;&#x2F;strong&gt; (built in way to do formal releases)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;security&lt;&#x2F;strong&gt; (granular access controls and workflow permissions, bank level
security for web access (https), and better for Git operations (ssh keys))&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Git* is not primarily a way to manage projects, but rather a way to manage and
collaborate around files, with some project management thrown in. It is centered
around the work, which is the main point.&lt;&#x2F;p&gt;
&lt;p&gt;Other tools have more advanced project management features, which are needed at
times. But they are missing a key ingredient: tight integration with your files.
The closer you can keep your project management and other metadata to the actual
work, the better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📁 The file dilemma</title>
        <published>2025-08-14T00:00:00+00:00</published>
        <updated>2025-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0213-the-file-dilemma/"/>
        <id>https://bec-systems.com/blog/0213-the-file-dilemma/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0213-the-file-dilemma/">&lt;p&gt;There is this movement against files in most disciplines. Files are hard to
manage, track, version, and secure (unless you use Git). Thus, a lot of tools
have moved to SaaS (software-as-a-service) applications in the cloud. Jon
Hirschtick
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;jon-hirschtick-founder-of-solidworks-and-onshape&#x2F;1575&quot;&gt;articulates this point of view&lt;&#x2F;a&gt;
very well. Cloud and APIs are the new “file.”&lt;&#x2F;p&gt;
&lt;p&gt;I’d like to present a few counterpoints.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integration:&lt;&#x2F;strong&gt; One of the ways we add value fast is integrating systems.
This is due to the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Network_effect&quot;&gt;network effect&lt;&#x2F;a&gt;, where
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Metcalfe&amp;#x27;s_law&quot;&gt;Metcalfe&lt;&#x2F;a&gt; defines the value as
the square of the number of nodes (or in our case integrated systems or types
of data). When we can integrate multiple types of data (say hardware,
software, and mechanical), the value increase is much greater than just
linear.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AI&lt;&#x2F;strong&gt;: AI needs context to be effective. The easiest way to provide context
is to run a local agent that has access to files that are in an open format.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;modelcontextprotocol.io&#x2F;&quot;&gt;MCP&lt;&#x2F;a&gt; (Model Context Protocol) may be
another way.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Accessibility:&lt;&#x2F;strong&gt; One of the problems with SaaS and APIs is you don’t really
own the data. Ten years down the road, are you still going to have access to
it? Are you still going to have the tools needed to use the data?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Files are flexible and scale. The success of Linux evidences this
(which adopts the Unix philosophy that everything is a file), the web (it still uses a
bunch of plain-text files for every site), and software development (anyone
ever heard of source code?). Software is by far the largest and most complex systems
humans have created, and it is still 99% based on the lowly text file. Since its
inception in 1991, the Linux kernel has had more than 20,000 contributors.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;jon-hirschtick-founder-of-solidworks-and-onshape&#x2F;1575&quot;&gt;Onshape&lt;&#x2F;a&gt;
is impressive, but it is a long way from scaling to projects of this size and
longevity.&lt;&#x2F;p&gt;
&lt;p&gt;The reality is that a mix of files and APIs is no doubt required. However, if
you want scalability and flexibility, I’m not sure you want to throw out files. GUI
technologies have been trying to do this for decades, but
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0191-text-based-formats-and-command-line-tools-are-the-future&#x2F;&quot;&gt;HTML and friends&lt;&#x2F;a&gt;
are still king (anyone remember Flash?).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 AI and documentation - close the loop</title>
        <published>2025-08-13T00:00:00+00:00</published>
        <updated>2025-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0212-ai-and-documentation-close-the-loop/"/>
        <id>https://bec-systems.com/blog/0212-ai-and-documentation-close-the-loop/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0212-ai-and-documentation-close-the-loop/">&lt;p&gt;Starting with good documentation is often a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0211-ai-is-the-new-compiler&#x2F;&quot;&gt;better way to use AI&lt;&#x2F;a&gt;.
However, you can also close the loop and have AI update the documentation when
it is finished. It can fill in details, clean things up, etc. This closes the
loop. Then repeat.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;ai-doc-loop.png&quot; alt=&quot;ai-doc-loop&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤖 AI is the new compiler</title>
        <published>2025-08-12T00:00:00+00:00</published>
        <updated>2025-08-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0211-ai-is-the-new-compiler/"/>
        <id>https://bec-systems.com/blog/0211-ai-is-the-new-compiler/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0211-ai-is-the-new-compiler/">&lt;p&gt;There are two ways to use AI:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Start with a vague prompt and keep prompting until we get the result we want.&lt;&#x2F;li&gt;
&lt;li&gt;Point the AI at documentation, and keep updating the documentation until it is
clear enough that AI can do the right thing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Even though it takes more time up front, in the end, the second approach will be
faster and more efficient because building a cohesive picture from a long string
of sloppy prompts is difficult, even with something as capable as AI. AI coding
engines are not free, so efficiency matters.&lt;&#x2F;p&gt;
&lt;p&gt;AI is the new compiler – IF we choose to use it that way.&lt;&#x2F;p&gt;
&lt;p&gt;Writing clean code is a skill. So is writing clean documentation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✨ Anyone can write scripts now</title>
        <published>2025-08-11T00:00:00+00:00</published>
        <updated>2025-08-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0210-anyone-can-write-scripts-now/"/>
        <id>https://bec-systems.com/blog/0210-anyone-can-write-scripts-now/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0210-anyone-can-write-scripts-now/">&lt;p&gt;With Claude Code (and likely many other AI technologies), anyone can write
scripts now. Instead of writing in a technical language like Python or Bash, you
can now write a sequence of commands with some rules in plain English, and
Claude transforms these into the technical bits to make it happen.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Low-code_development_platform&quot;&gt;Low-code&lt;&#x2F;a&gt; is
finally a reality. You can keep these as Claude commands, or have Claude write
permanent scripts, programs, tools, etc.&lt;&#x2F;p&gt;
&lt;p&gt;It is now easier than ever to build YOUR Platform.&lt;&#x2F;p&gt;
&lt;p&gt;See
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;how-to-create-rules-for-claude-KlzVkYwVTn2DZCyUP89QJw?1=d&quot;&gt;this summary&lt;&#x2F;a&gt;
or
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0204-how-i-use-claude-code-to-help-publish-this-blog&#x2F;&quot;&gt;this example&lt;&#x2F;a&gt;
for more information.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✏️ Effective Communication (Sketching)</title>
        <published>2025-08-08T00:00:00+00:00</published>
        <updated>2025-08-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0209-effective-communication-sketching/"/>
        <id>https://bec-systems.com/blog/0209-effective-communication-sketching/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0209-effective-communication-sketching/">&lt;p&gt;Sketching is kind of like writing cursive—it engages a dynamic in our brains
that inspires creativity. As we mostly use computers, it takes extra effort to
pick up pen or pencil, but surprising things happen when we do. It engages
broader areas of our brain, and there is a flow that comes from the lack of
restraints our digital tools have. So perhaps sketching is mostly about
communicating with ourselves, but we can still easily snap a photo with a phone
and share it. This is perhaps the lowest friction form of drawing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;issues&#x2F;294&quot;&gt;Here is an example&lt;&#x2F;a&gt; in
thinking through a hard problem where sketching really helped.&lt;&#x2F;p&gt;
&lt;p&gt;One thing that helps me cultivate a sketching habit is to always have paper and
a pencil or pen out on the desk when working. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;emergent-task-timer&#x2F;1421&quot;&gt;daily worksheet&lt;&#x2F;a&gt; is
always on my desk—the back is a good place to sketch and write notes. I also
need to get into the habit of using a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;book-review-bullet-journal&#x2F;391&#x2F;7?u=cbrake&quot;&gt;journal&lt;&#x2F;a&gt;
more.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎨 Effective Communication (Drawing)</title>
        <published>2025-08-07T00:00:00+00:00</published>
        <updated>2025-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0208-effective-communication-drawing/"/>
        <id>https://bec-systems.com/blog/0208-effective-communication-drawing/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0208-effective-communication-drawing/">&lt;p&gt;We’ve already explored 4 modes of
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;communication&#x2F;&quot;&gt;communication&lt;&#x2F;a&gt; (audio,
written, images, video). Drawings are another, and today it is even easier to do
with tools like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;excalidraw.com&#x2F;&quot;&gt;Excalidraw&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;draw.io&#x2F;&quot;&gt;Draw.io&lt;&#x2F;a&gt;. It is easy to copy drawings from both into other
applications.&lt;&#x2F;p&gt;
&lt;p&gt;A clean drawing&#x2F;diagram brings another level of professionalism to your work.&lt;&#x2F;p&gt;
&lt;p&gt;Drawing with AI is another option, but I have not figured out how to use that
yet.&lt;&#x2F;p&gt;
&lt;p&gt;One thing that has worked well for me is to use a single Excalidraw drawing as
an infinite canvas. This way I can easily see content I’ve created before, reuse
it, or use it for inspiration.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;a&#x2F;ad720f3be3088fc0c85202fe188123e99be03289.png&quot; alt=&quot;excalidraw drawing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📹 Effective Communication (Video)</title>
        <published>2025-08-06T00:00:00+00:00</published>
        <updated>2025-08-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0207-effective-communication-video/"/>
        <id>https://bec-systems.com/blog/0207-effective-communication-video/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0207-effective-communication-video/">&lt;p&gt;Video is now an important way to communicate. The most obvious type is Zoom
calls. But there are other ways we can use video such as screencasting,
recording demos, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Position a decent camera at a good angle. Shooting up your nose probably isn’t a
good camera position.&lt;&#x2F;p&gt;
&lt;p&gt;Screencasts are a scaling superpower. Record how you do something and share it
with people learning. Have them write the documentation or checklist.&lt;&#x2F;p&gt;
&lt;p&gt;Screencasts may be a better way to demo. Record and share the demo ahead of
time, then discuss it in a meeting.&lt;&#x2F;p&gt;
&lt;p&gt;With a screencast, it’s even more important to have good audio. In a meeting,
people will overlook bad audio because you have a captive audience. But in a
recorded video, people will likely quit watching if the audio is bad. So get a
decent
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;audio-technica-at2020usb-microphone-review&#x2F;578&quot;&gt;podcasting mic&lt;&#x2F;a&gt;
or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;video-conferencing-notes&#x2F;117&quot;&gt;headset&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Learn OBS Studio - this is a professional way to record screencasts that is
free. I’ve found that
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;how-to-record-screencasts-using-obs&#x2F;1048&quot;&gt;setting up a 1080p (1920x1080) section&lt;&#x2F;a&gt;
of my screen to record works well. Drag, resize, and stack the applications you
want to display in this section of the screen, then just record that single
scene. This is much simpler than setting up a separate scene for every
application.&lt;&#x2F;p&gt;
&lt;p&gt;If you are working with hardware, get a document camera to video stuff on the
lab bench.&lt;&#x2F;p&gt;
&lt;p&gt;And don’t forget your phone takes excellent video - we all should probably make
better use of this capability.&lt;&#x2F;p&gt;
&lt;p&gt;When possible, record in MP4 format. This format plays easily in most browsers,
so you can simply upload a file to a file sharing site, and people can
automatically play it in their browser.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve yet to figure out lighting, green screens, etc. - lots to learn yet.
Systems like this can always be improved, so keep improving.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📸 Effective Communication (Images)</title>
        <published>2025-08-05T00:00:00+00:00</published>
        <updated>2025-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0206-effective-communication-images/"/>
        <id>https://bec-systems.com/blog/0206-effective-communication-images/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0206-effective-communication-images/">&lt;blockquote&gt;
&lt;p&gt;“A picture is worth a thousand words.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;There are many times when a screenshot or a photograph can drastically improve
the rate of communication. Therefore, figure out ways to do this efficiently.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure your computer system has an efficient way to capture and mark up
screenshots – preferably in the same application. Spectacle in KDE is
excellent. I’m sure there are good options for other environments.&lt;&#x2F;p&gt;
&lt;p&gt;Also have a quick way to get photographs off your phone into a message. I use
the Google Magnifier app on Android, sharing to a “Note to self” in
Signal, then copying the image in Signal desktop on my PC. This is much faster
than waiting for the image to upload to Google Photos.&lt;&#x2F;p&gt;
&lt;p&gt;What works for you?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✍️ Effective communication (Written)</title>
        <published>2025-08-04T00:00:00+00:00</published>
        <updated>2025-08-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0205-effective-communication-written/"/>
        <id>https://bec-systems.com/blog/0205-effective-communication-written/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0205-effective-communication-written/">&lt;p&gt;For starters, consider Michael Lynch’s
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;refactoringenglish.com&#x2F;chapters&#x2F;techniques-for-writing-emails&#x2F;&quot;&gt;“Underused Techniques for Effective Emails”&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A few points in summary:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Put the most important information first.&lt;&#x2F;li&gt;
&lt;li&gt;Use headings, code blocks, and other formatting.&lt;&#x2F;li&gt;
&lt;li&gt;Be succinct.&lt;&#x2F;li&gt;
&lt;li&gt;Provide context by quoting and replying
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0202-top-vs-bottom-posting-in-email&#x2F;&quot;&gt;bottom posting&lt;&#x2F;a&gt;
in emails and quoting in PR&#x2F;issue threads). Don’t make your readers read the
entire discussion and try to extrapolate the context of what you are trying to
say.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤖 How I use Claude Code to help publish this blog</title>
        <published>2025-08-01T00:00:00+00:00</published>
        <updated>2025-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0204-how-i-use-claude-code-to-help-publish-this-blog/"/>
        <id>https://bec-systems.com/blog/0204-how-i-use-claude-code-to-help-publish-this-blog/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0204-how-i-use-claude-code-to-help-publish-this-blog/">&lt;p&gt;I have been using Claude Code to help with the following tasks on this blog:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;proofread (including detecting
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;refactoringenglish.com&#x2F;chapters&#x2F;passive-voice-considered-harmful&#x2F;&quot;&gt;passive voice&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;add tags&lt;&#x2F;li&gt;
&lt;li&gt;add an emoji to the title&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These are not rocket science, but they also take time and are something AI does
pretty well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;IcOl5dIrWP8&quot;&gt;This video&lt;&#x2F;a&gt; shows how the process works.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎧 Effective communication (Audio)</title>
        <published>2025-07-31T00:00:00+00:00</published>
        <updated>2025-07-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0203-effective-communication-audio/"/>
        <id>https://bec-systems.com/blog/0203-effective-communication-audio/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0203-effective-communication-audio/">&lt;p&gt;Effective communication requires that those receiving information from us can
easily process it. I’ve been on way too many calls where you can barely hear the
speaker due to echo, background noise, or other audio problems. Some things I’ve
found helpful:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use a headset. This eliminates any possibility of feedback from speakers into
the mic.&lt;&#x2F;li&gt;
&lt;li&gt;Use a good noise-canceling&#x2F;rejecting mic, especially in noisy environments.
Some headsets (like the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;video-conferencing-notes&#x2F;117&quot;&gt;Sennheiser SC series&lt;&#x2F;a&gt;)
block background noise amazingly well. Good podcast mics (like the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;audio-technica-at2020usb-microphone-review&#x2F;578&#x2F;2&quot;&gt;AT2020&lt;&#x2F;a&gt;)
are usually directional and block noise pretty well, especially when
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;audio-technica-at8700-mic-boom-review&#x2F;1573&quot;&gt;positioned close to your mouth&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Use a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;video-conferencing-notes&#x2F;117&#x2F;9?u=cbrake&quot;&gt;Bluetooth headset&lt;&#x2F;a&gt;
with your phone that has noise blocking in the microphone. Most
noise-canceling headsets focus on blocking background noise for your benefit.
On calls, optimize for your listener’s benefit.&lt;&#x2F;li&gt;
&lt;li&gt;Pro tip: never use the speakers and mic in your laptop, even if it is a Mac.&lt;&#x2F;li&gt;
&lt;li&gt;Pro tip 2: don’t use speakerphone mode on your phone – especially for group
calls.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Don’t be the one who disrupts a group call with crummy audio. You are a
professional – use professional gear.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📧 Top vs bottom posting in email</title>
        <published>2025-07-29T00:00:00+00:00</published>
        <updated>2025-07-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0202-top-vs-bottom-posting-in-email/"/>
        <id>https://bec-systems.com/blog/0202-top-vs-bottom-posting-in-email/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0202-top-vs-bottom-posting-in-email/">&lt;p&gt;I was thinking about computing history this morning, and I wonder how many young
people even know that
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Posting_style&quot;&gt;bottom posting in email&lt;&#x2F;a&gt; is even a
thing? Some of the older OSS projects
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lore.kernel.org&#x2F;rust-for-linux&#x2F;2025021954-flaccid-pucker-f7d9@gregkh&#x2F;&quot;&gt;still have this culture&lt;&#x2F;a&gt;,
but I suspect that most emails sent today use top posting.&lt;&#x2F;p&gt;
&lt;p&gt;I find myself getting lazy and top posting, but it is so much more considerate
of the reader (especially with modern email readers that thread messages) to
bottom post and only keep the text needed to understand the context or your
reply. The old emails are still in the thread and easily viewable – there is no
reason to repeat the entire discussion chain in every email.&lt;&#x2F;p&gt;
&lt;p&gt;Smart clients like Gmail somewhat alleviate this concern by hiding previous
message details, but it often hides too much, and you have to expand parts of
the old message to see what a response is referencing. And with top posting, you
often have to repeat the context of your reply vs. just including your reply
directly below the relevant context.&lt;&#x2F;p&gt;
&lt;p&gt;This is one reason discussions in Git* issues and other forum type threads can
be so much more effective – you can more easily follow the discussion over
time. But you can get near the same efficiency with email if you take a little
care.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎉 200 posts</title>
        <published>2025-07-28T00:00:00+00:00</published>
        <updated>2025-07-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0201-200-posts/"/>
        <id>https://bec-systems.com/blog/0201-200-posts/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0201-200-posts/">&lt;p&gt;This marks the 201st post I’ve sent – 2&#x2F;3’s of the way through the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jonathanstark.com&#x2F;daily&#x2F;20250512-1745-weekly-vs-daily&quot;&gt;300 bad posts&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;How is it going? I still enjoy the process and the thinking it brings. However,
it is getting a little bit more difficult recently to keep the discipline,
especially with busy project and summer schedules.&lt;&#x2F;p&gt;
&lt;p&gt;I continue to have many more ideas than time to write, so coming up with ideas
is not a problem.&lt;&#x2F;p&gt;
&lt;p&gt;The publishing process has been further streamlined using Claude Code – will
share more details on that in the near future.&lt;&#x2F;p&gt;
&lt;p&gt;If you have any feedback, please reply – always welcome!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔗 Integration, not isolation (part 2)</title>
        <published>2025-07-24T00:00:00+00:00</published>
        <updated>2025-07-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0200-integration-not-isolation-part-2/"/>
        <id>https://bec-systems.com/blog/0200-integration-not-isolation-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0200-integration-not-isolation-part-2/">&lt;p&gt;We recently
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0199-integration-not-isolation&#x2F;&quot;&gt;discussed integration&lt;&#x2F;a&gt;,
not isolation from a technical perspective.&lt;&#x2F;p&gt;
&lt;p&gt;In an organizational context, we can have integrated cross-functional teams, or
isolated silos.&lt;&#x2F;p&gt;
&lt;p&gt;And the easiest way to
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0173-what-is-the-easiest-way-to-avoid-silos&#x2F;&quot;&gt;avoid silos&lt;&#x2F;a&gt;
is transparency and common systems. These things are hard – they don’t just
happen automatically.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔗 Integration, not isolation</title>
        <published>2025-07-23T00:00:00+00:00</published>
        <updated>2025-07-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0199-integration-not-isolation/"/>
        <id>https://bec-systems.com/blog/0199-integration-not-isolation/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0199-integration-not-isolation/">&lt;p&gt;In a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;046&#x2F;&quot;&gt;recent discussion&lt;&#x2F;a&gt;, the comment was made that
containers are not always a good fit for edge&#x2F;embedded devices, as they are
designed for isolation (which is useful at times for cloud workloads), but with
embedded, we want tight integration. Justin Schneck advocates file-system layers
as an alternative. Isolation from the kernel is a feature in the cloud, but in
embedded systems, we often need direct access to the kernel (integration).&lt;&#x2F;p&gt;
&lt;p&gt;We, as an industry, perhaps focus too much on isolation (security, protection,
every app bundles its own stack of dependencies, etc.). Short term, this is
convenient. Long term, this can lead to bloat, inefficiencies, and brittle
systems.&lt;&#x2F;p&gt;
&lt;p&gt;Can we have integration AND decoupling? That is a topic for future thinking…&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 What do we mean by scaling?</title>
        <published>2025-07-22T00:00:00+00:00</published>
        <updated>2025-07-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0198-what-do-we-mean-by-scaling/"/>
        <id>https://bec-systems.com/blog/0198-what-do-we-mean-by-scaling/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0198-what-do-we-mean-by-scaling/">&lt;p&gt;This can mean many things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;More units sold&lt;&#x2F;li&gt;
&lt;li&gt;More customers served&lt;&#x2F;li&gt;
&lt;li&gt;More people doing the work&lt;&#x2F;li&gt;
&lt;li&gt;More features&lt;&#x2F;li&gt;
&lt;li&gt;More innovation&lt;&#x2F;li&gt;
&lt;li&gt;More models produced&lt;&#x2F;li&gt;
&lt;li&gt;More model options&lt;&#x2F;li&gt;
&lt;li&gt;More quality&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We could go on, but basically we mean more of something over time. And the “over
time” part means we need to be thinking long-term. You cannot scale with
short-term thinking—this is a logical fallacy. This is why YOUR Platform is so
important.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Open loops -&gt; technical debt</title>
        <published>2025-07-21T00:00:00+00:00</published>
        <updated>2025-07-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0197-open-loops-technical-debt/"/>
        <id>https://bec-systems.com/blog/0197-open-loops-technical-debt/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0197-open-loops-technical-debt/">&lt;p&gt;If something is corrected, it needs to be fed back and incorporated, so you
don’t keep redoing the same stuff over and over and eventually bury yourself in
technical debt.&lt;&#x2F;p&gt;
&lt;p&gt;Effective organizations close the loop.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧩 Composing is hard, complexity is easy</title>
        <published>2025-07-18T00:00:00+00:00</published>
        <updated>2025-07-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0196-composing-is-hard-complexity-is-easy/"/>
        <id>https://bec-systems.com/blog/0196-composing-is-hard-complexity-is-easy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0196-composing-is-hard-complexity-is-easy/">&lt;p&gt;We’ve recently explored the idea that
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0194-simplicity-scales&#x2F;&quot;&gt;composing simple things is the way to scale&lt;&#x2F;a&gt;.
But this is harder than just cranking something out. Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It is much easier to create an Excel spreadsheet than write a Python script to
process a CSV file and create a chart which can be later automated in a CI
process.&lt;&#x2F;li&gt;
&lt;li&gt;It is much easier to create lots of custom structs with lots of fields than to
create simple structs that can be used for multiple purposes.&lt;&#x2F;li&gt;
&lt;li&gt;It is much easier to add additional functions to an interface than to create
additional well-thought-out interfaces.&lt;&#x2F;li&gt;
&lt;li&gt;It is quicker to hack on a Raspbian image than to set up a proper Yocto build
for a Raspberry Pi single board computer that can be more easily maintained
long-term.&lt;&#x2F;li&gt;
&lt;li&gt;It is quicker to draw a schematic with generic parts and manually assign
manufacturer part numbers&#x2F;footprints, than set up a proper parts library that
will make subsequent designs and changes easier.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If your task is a one-off project, or something only you will ever interact
with, then the easy path may be fine. However, if you want to scale, the hard
path is the way forward.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎼 Compose software like music</title>
        <published>2025-07-17T00:00:00+00:00</published>
        <updated>2025-07-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0195-compose-software-like-music/"/>
        <id>https://bec-systems.com/blog/0195-compose-software-like-music/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0195-compose-software-like-music/">&lt;p&gt;Music is an interesting thing – a beautiful arrangement is composed of very
simple constructs – a handful of simple notes on a relatively simple scale. The
brilliance is in how these simple constructs are arranged.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise, brilliant software is composed of simple data structures and
interfaces. Just like music, there is no limit to the ways these simple
constructs can be arranged.&lt;&#x2F;p&gt;
&lt;p&gt;Conversely, complex constructs are very limited in how they can be used.&lt;&#x2F;p&gt;
&lt;p&gt;Put the complexity in the arrangement, not the constructs.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌱📈 Simplicity scales</title>
        <published>2025-07-16T00:00:00+00:00</published>
        <updated>2025-07-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0194-simplicity-scales/"/>
        <id>https://bec-systems.com/blog/0194-simplicity-scales/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0194-simplicity-scales/">&lt;p&gt;When programming, we learn that
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.thoughtworks.com&#x2F;en-us&#x2F;insights&#x2F;blog&#x2F;programming-languages&#x2F;mistakes-to-avoid-when-coming-from-an-object-oriented-language&quot;&gt;simple interfaces&lt;&#x2F;a&gt;
and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;2432&#x2F;struggling-to-scale-your-iot-system-simplify-your-data&#x2F;&quot;&gt;simple data structures&lt;&#x2F;a&gt;
are good, because they are flexible.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0191-text-based-formats-and-command-line-tools-are-the-future&#x2F;&quot;&gt;Simple file formats&lt;&#x2F;a&gt;
are the same. We can do way more with a CSV or Markdown file in terms of
presentation and automation than we can with Excel or Word documents.&lt;&#x2F;p&gt;
&lt;p&gt;This seems counterintuitive – Excel is a very powerful tool, and the right
tool for many uses. However, an Excel file is not as composable as simple
formats. As an example, consider the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;im-planning-a-family-trip-to-s-zg96NEdJRA6Ekwt7vvxioQ?0=a&quot;&gt;assets&lt;&#x2F;a&gt;
of a Perplexity labs project. They are Python scripts, CSV, Markdown, etc. Why?
Because a powerful tool, like AI, can do more with simple formats.&lt;&#x2F;p&gt;
&lt;p&gt;Complex formats (Ex: Excel) allow a single person to do a lot in the short term,
but simple formats allow a team and automation to do way more over time.&lt;&#x2F;p&gt;
&lt;p&gt;The way to scale YOUR Platform is to compose simple interfaces, data structures,
and file formats. A little more work short term, but way more powerful
long-term.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📏 Goodhart&#x27;s law</title>
        <published>2025-07-15T00:00:00+00:00</published>
        <updated>2025-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0193-goodhart-s-law/"/>
        <id>https://bec-systems.com/blog/0193-goodhart-s-law/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0193-goodhart-s-law/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Goodhart&amp;#x27;s_law&quot;&gt;Goodhart’s law&lt;&#x2F;a&gt; states: “When a
measure becomes a target, it ceases to be a good measure”.&lt;&#x2F;p&gt;
&lt;p&gt;Metrics are useful, but they are just a tool, not the goal. If Metrics become
the goal, then they undermine collaboration, trust, and transparency.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 Why GUI development tools don&#x27;t scale</title>
        <published>2025-07-10T00:00:00+00:00</published>
        <updated>2025-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0192-why-gui-development-tools-don-t-scale/"/>
        <id>https://bec-systems.com/blog/0192-why-gui-development-tools-don-t-scale/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0192-why-gui-development-tools-don-t-scale/">&lt;p&gt;This is an interesting read:
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mtlynch.io&#x2F;notes&#x2F;guis-are-antisocial&#x2F;&quot;&gt;GUIs are Antisocial&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This hits on an important point… GUI tools don’t scale, because they are not
social. Two of the most complex efforts humans have accomplished are chip design
and software development – both are firmly entrenched in
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0191-text-based-formats-and-command-line-tools-are-the-future&#x2F;&quot;&gt;text based formats and command line tools&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔭 Text based formats and command-line tools are the future</title>
        <published>2025-07-08T00:00:00+00:00</published>
        <updated>2025-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0191-text-based-formats-and-command-line-tools-are-the-future/"/>
        <id>https://bec-systems.com/blog/0191-text-based-formats-and-command-line-tools-are-the-future/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0191-text-based-formats-and-command-line-tools-are-the-future/">&lt;p&gt;For the past three decades, we have been told that graphical user interfaces
(GUIs) will revolutionize computer use and even programming. In many ways, they
have made computers very accessible for the average person – especially phone
UIs.&lt;&#x2F;p&gt;
&lt;p&gt;However, the command-line tools and text files are still the standard for
building stuff. Most useful programming is done in text based programming
languages. Even most UIs are still implemented in text based languages such as
HTML and CSS. In spite of the many graphical options that have come and gone –
HTML remains the king.&lt;&#x2F;p&gt;
&lt;p&gt;Why do text based formats and command line tools work so well?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Text-based formats are easy to work with (collaborate, edit, tooling).&lt;&#x2F;li&gt;
&lt;li&gt;Command-line based tools are easy to automate (build systems, CI, CD).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The coming AI storm makes these factors even more important. Because AI coding
is all about tooling, collaboration, and automation.&lt;&#x2F;p&gt;
&lt;p&gt;If we dig a little deeper, text-based formats and command-line tools are “open”
– you can do things that were not originally planned. Open formats and tools do
not lock you into a single paradigm, but rather allow you to build YOUR Platform
to meet your needs.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Flipping the playbook for AI coding</title>
        <published>2025-07-02T00:00:00+00:00</published>
        <updated>2025-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0190-flipping-the-playbook-for-ai-coding/"/>
        <id>https://bec-systems.com/blog/0190-flipping-the-playbook-for-ai-coding/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0190-flipping-the-playbook-for-ai-coding/">&lt;p&gt;A lot of focus these days is on “good AI prompts.”&lt;&#x2F;p&gt;
&lt;p&gt;Some of the best prompts may be documentation and tests. Write your
&lt;code&gt;CHANGELOG.md&lt;&#x2F;code&gt; entries first, then update the documentation, then write the
tests, then tell the AI to update the code to match.&lt;&#x2F;p&gt;
&lt;p&gt;We tend to get it backwards—asking AI to generate tests and documentation
after the code. Flip this and do the docs and tests first.&lt;&#x2F;p&gt;
&lt;p&gt;Your thinking will be better, and you’ll move faster.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧑‍💻 The first step in AI coding</title>
        <published>2025-07-01T00:00:00+00:00</published>
        <updated>2025-07-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0189-the-first-step-in-ai-coding/"/>
        <id>https://bec-systems.com/blog/0189-the-first-step-in-ai-coding/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0189-the-first-step-in-ai-coding/">&lt;p&gt;✔️ Should be “How does this work?”&lt;&#x2F;p&gt;
&lt;p&gt;❌ NOT “Implement this feature.”&lt;&#x2F;p&gt;
&lt;p&gt;Understanding should precede any work, especially in complex systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Alternatives to meetings</title>
        <published>2025-06-26T00:00:00+00:00</published>
        <updated>2025-06-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0188-alternatives-to-meetings/"/>
        <id>https://bec-systems.com/blog/0188-alternatives-to-meetings/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0188-alternatives-to-meetings/">&lt;p&gt;✔️ Instead of presenting in a meeting, record a screencast and share it.&lt;&#x2F;p&gt;
&lt;p&gt;✔️ &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0099-the-importance-of-git-commit-push-often&#x2F;&quot;&gt;Publish your work often.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;✔️ Utilize notifications in workflow tools.&lt;&#x2F;p&gt;
&lt;p&gt;✔️ Utilize a team chat tool such as Signal, Slack, Discourse chat, Discord, etc.. This does wonders for bonding teams (especially distributed teams). You can always mute it when doing deep work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🥣 The two ingredients for agility</title>
        <published>2025-06-24T00:00:00+00:00</published>
        <updated>2025-06-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0187-the-two-ingredients-for-agility/"/>
        <id>https://bec-systems.com/blog/0187-the-two-ingredients-for-agility/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0187-the-two-ingredients-for-agility/">&lt;p&gt;✔️ &lt;strong&gt;Low friction&lt;&#x2F;strong&gt;: tooling and workflows that allow anyone to make changes
easily. (good build systems, clean libraries, release automation, etc.)&lt;&#x2F;p&gt;
&lt;p&gt;✔️ &lt;strong&gt;Confidence&lt;&#x2F;strong&gt;: what we are doing is not going to break things. (CI,
end-to-end testing, review, etc.)&lt;&#x2F;p&gt;
&lt;p&gt;#1 is obvious. #2 is subtle – if we don’t have confidence in the work, we
will avoid it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>♻️ How to iterate quickly on hardware</title>
        <published>2025-06-23T00:00:00+00:00</published>
        <updated>2025-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0186-how-to-iterate-quickly-on-hardware/"/>
        <id>https://bec-systems.com/blog/0186-how-to-iterate-quickly-on-hardware/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0186-how-to-iterate-quickly-on-hardware/">&lt;p&gt;Today, we mostly think of iterating quickly on software, but it is becoming
increasingly possible to also do this with hardware. A few ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Printed circuit boards (PCBs) are now relatively cheap and quick to
manufacture in low quantities from companies like JLCPCB (you can have a new
PCB in less than a week at a very reasonable cost).&lt;&#x2F;li&gt;
&lt;li&gt;Companies like JLCPCB and Macrofab offer prototype assembly services.&lt;&#x2F;li&gt;
&lt;li&gt;It is practical to
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;building-pcb-assembly-prototypes&#x2F;1486&quot;&gt;assemble your own&lt;&#x2F;a&gt;
prototype PCBs quickly.&lt;&#x2F;li&gt;
&lt;li&gt;You can now do more CI&#x2F;CD type things with PCB design tools. KiCad has a
powerful DRC rules engine and the ability to script a lot of operations
(including generating outputs) from the command line. Run ERC&#x2F;DRC in CI and
generate outputs in CD. This allows you to make and deploy changes with a high
level of confidence.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&#x2F;parts&quot;&gt;Verified parts libraries&lt;&#x2F;a&gt; allow you to
easily reuse electrical components in new designs.&lt;&#x2F;li&gt;
&lt;li&gt;Spice simulation tools allow you to verify designs before building a PCB –
again, you can have a higher confidence that things will work.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;036&#x2F;&quot;&gt;3D printing in production&lt;&#x2F;a&gt; allows you to make
mechanical improvements without expensive tooling changes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;tlsl01uxUfE&quot;&gt;Intelligent part numbering schemes&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&#x2F;gitplm&quot;&gt;PLM tools&lt;&#x2F;a&gt; allow you to efficiently and
reliably manage changes.&lt;&#x2F;li&gt;
&lt;li&gt;Use OSS tools
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;1670&#x2F;reflections-on-kicad-and-eda-tools&#x2F;&quot;&gt;like KiCad&lt;&#x2F;a&gt;
where possible so anyone can make changes.&lt;&#x2F;li&gt;
&lt;li&gt;Use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;git&#x2F;&quot;&gt;Git workflows&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above is YOUR Platform. Here’s the thing – the more complex and the higher
value your product is, the more important it is to be able to iterate quickly
and confidently on both hardware and software. As an example, Tesla updates the
software in their cars frequently and continuously makes mechanical improvements
(sometimes as many as 120-160 changes per week). If Tesla can do it with cars,
you can probably do it with your low-volume industrial product.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 Modern product development is a collaborative endeavor</title>
        <published>2025-06-20T00:00:00+00:00</published>
        <updated>2025-06-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0185-modern-product-development-is-a-collaborative-endeavor/"/>
        <id>https://bec-systems.com/blog/0185-modern-product-development-is-a-collaborative-endeavor/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0185-modern-product-development-is-a-collaborative-endeavor/">&lt;p&gt;There is no way around this – even if you are a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;book-review-company-of-one&#x2F;1544&quot;&gt;Company of One&lt;&#x2F;a&gt;.
You must collaborate with:&lt;&#x2F;p&gt;
&lt;p&gt;▶ OSS communities who provide the tools and software you use,&lt;&#x2F;p&gt;
&lt;p&gt;▶ Your customers – if you are not learning from them, you probably won’t
understand and fulfill their needs,&lt;&#x2F;p&gt;
&lt;p&gt;▶ and Your team.&lt;&#x2F;p&gt;
&lt;p&gt;While the last item on the list is obvious, the first two are less obvious, but
perhaps just as important.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✨ Use the most advanced technology that is comfortable in your product design</title>
        <published>2025-06-19T00:00:00+00:00</published>
        <updated>2025-06-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0184-use-the-most-advanced-technology-that-is-comfortable-in-your-product-design/"/>
        <id>https://bec-systems.com/blog/0184-use-the-most-advanced-technology-that-is-comfortable-in-your-product-design/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0184-use-the-most-advanced-technology-that-is-comfortable-in-your-product-design/">&lt;p&gt;Some examples:&lt;&#x2F;p&gt;
&lt;p&gt;▶ When designing a PCB, put down the smallest packages you are comfortable
working with. Example: put down 0603’s instead of 0805’s, even if you don’t need
the space right now.&lt;&#x2F;p&gt;
&lt;p&gt;▶ Use a MCU with the most performance and RAM&#x2F;Flash that is reasonable. Use a
STM32 instead of a PIC16.&lt;&#x2F;p&gt;
&lt;p&gt;▶ Everything else being pretty much equal, use Go instead of Python.&lt;&#x2F;p&gt;
&lt;p&gt;Why?&lt;&#x2F;p&gt;
&lt;p&gt;✅ You may not need the space now, but the next iteration or variant of the
product will likely be smaller, so why not plan for that now if it does not cost
you anything?&lt;&#x2F;p&gt;
&lt;p&gt;✅ Modern embedded systems that support field updates are flexible and can do a
lot. New features will be requested. Plan for that now.&lt;&#x2F;p&gt;
&lt;p&gt;✅ Python may be good enough now, but what happens when you need to add a
handful more threads, more features, deploy to other architectures, and need
higher performance?&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the thing – it is impossible to predict all the directions a product
will take. Set yourself up now to be able to reuse what you’re doing.&lt;&#x2F;p&gt;
&lt;p&gt;🔭 Product VISION == Smart technology choices&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 When to update application dependencies?</title>
        <published>2025-06-18T00:00:00+00:00</published>
        <updated>2025-06-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0183-when-to-update-application-dependencies/"/>
        <id>https://bec-systems.com/blog/0183-when-to-update-application-dependencies/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0183-when-to-update-application-dependencies/">&lt;p&gt;Most modern languages (Node.js, Python, Rust, Go, Zig, Elm, etc.) have their own
package manager. So when should we update package dependencies? How about at the
beginning of every PR cycle? I’m working on making this my standard practice
when starting a new feature in an application – first, update all dependencies.
There are several advantages to this flow:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Updating frequently means you are dealing with small changes.&lt;&#x2F;li&gt;
&lt;li&gt;Updating at the start of a dev cycle also gives you a standard time to do
this. Otherwise, things like updating dependencies tend to get neglected.&lt;&#x2F;li&gt;
&lt;li&gt;Updating at the start of a dev cycle (vs end) gives you some time to exercise
new modules during development before merging.&lt;&#x2F;li&gt;
&lt;li&gt;You automatically get security updates without having to track these too
closely.&lt;&#x2F;li&gt;
&lt;li&gt;It feels right.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This also requires good tests, so that you can update with confidence. There
might also be an issue with a team if multiple developers are updating
dependencies at the same time. So in larger teams, perhaps one person or an
automated process should do this. The key thing is that it does get done, and
implement the needed automation to make this easy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>➡️ Frontload the boring stuff</title>
        <published>2025-06-16T00:00:00+00:00</published>
        <updated>2025-06-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0182-frontload-the-boring-stuff/"/>
        <id>https://bec-systems.com/blog/0182-frontload-the-boring-stuff/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0182-frontload-the-boring-stuff/">&lt;p&gt;Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Think about and write tests &lt;em&gt;before&lt;&#x2F;em&gt; implementing a new software feature.&lt;&#x2F;li&gt;
&lt;li&gt;Automate deployment of a new service &lt;em&gt;before&lt;&#x2F;em&gt; developing it.&lt;&#x2F;li&gt;
&lt;li&gt;Create eCAD libraries &lt;em&gt;before&lt;&#x2F;em&gt; doing the schematic&#x2F;layout work.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;architecture-decision-records&#x2F;334&quot;&gt;Document the architecture&lt;&#x2F;a&gt;
&lt;em&gt;before&lt;&#x2F;em&gt; implementing it.&lt;&#x2F;li&gt;
&lt;li&gt;Open a PR &lt;em&gt;before&lt;&#x2F;em&gt; doing the work, and explain what is going to be done.&lt;&#x2F;li&gt;
&lt;li&gt;Create a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;keepachangelog.com&#x2F;&quot;&gt;Changelog&lt;&#x2F;a&gt; entry describing the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;refactoringenglish.com&#x2F;chapters&#x2F;release-announcements&#x2F;&quot;&gt;benefit to the user&lt;&#x2F;a&gt;
of what you are doing, &lt;em&gt;before&lt;&#x2F;em&gt; writing the code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the end, you will go faster and do better work. Why? Because you are
frontloading the tedious details that are difficult to find time for &lt;em&gt;after&lt;&#x2F;em&gt; the
work is done.&lt;&#x2F;p&gt;
&lt;p&gt;This is the difference between the prototyping and product development mindset.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌿 A natural way to get more testing&#x2F;automation</title>
        <published>2025-06-06T00:00:00+00:00</published>
        <updated>2025-06-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0181-a-natural-way-to-get-more-testing-automation/"/>
        <id>https://bec-systems.com/blog/0181-a-natural-way-to-get-more-testing-automation/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0181-a-natural-way-to-get-more-testing-automation/">&lt;p&gt;One thing I’ve noticed is when I release more frequently, I tend to automate. If
releases only happen once every year, it is easy to neglect automation, CI&#x2F;CD,
etc. Automated tests are not needed as it is just quicker to manually test
everything. But, with frequent releases, there is a subtle push toward scripting
stuff, getting CI&#x2F;CD running, etc. Instead of demanding more tests&#x2F;automation,
perhaps decide to release more often, and the automation will naturally follow.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌒🌓🌔The four phases of product development</title>
        <published>2025-06-05T00:00:00+00:00</published>
        <updated>2025-06-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0180-the-four-phases-of-product-development/"/>
        <id>https://bec-systems.com/blog/0180-the-four-phases-of-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0180-the-four-phases-of-product-development/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;9&#x2F;917a9784cd1abd3d34fee35e1fedc4ecc78e41c8.png&quot; alt=&quot;phases&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each phase is produced by someone or something. And the problems arise when we
mix up who does what.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Great&#x2F;innovative ideas usually don’t come out of a committee. Truth is a solo
pursuit. Evaluate ideas in meetings, but don’t try to come up with them there.&lt;&#x2F;li&gt;
&lt;li&gt;When a team is involved, collaboration is required. The better your
collaboration culture&#x2F;workflow, the more efficient your team will be.&lt;&#x2F;li&gt;
&lt;li&gt;Manually building, testing, and deploying software is a waste of human time –
leave that to machines when possible.&lt;&#x2F;li&gt;
&lt;li&gt;Developers are horribly inept at testing&#x2F;evaluating their own work. Any
outside viewpoint is useful – especially with user interfaces.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The faster you can do this loop, the faster you’ll learn, and the quicker you
can build something useful.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⏩ Get on with it ...</title>
        <published>2025-06-04T00:00:00+00:00</published>
        <updated>2025-06-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0180-get-on-with-it/"/>
        <id>https://bec-systems.com/blog/0180-get-on-with-it/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0180-get-on-with-it/">&lt;p&gt;While many great ideas and algorithms germinate in deep work and solo thinking,
bringing a modern product (especially one containing software) to life require
many iterations with feedback and learning. So lets propose a new release
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;iterate-hardware-like-software&#x2F;139&quot;&gt;every week&lt;&#x2F;a&gt;.
But, the common objection is: we can’t do a quality release every week? A
monthly release seems more reasonable, then we have plenty of time to get it
right.&lt;&#x2F;p&gt;
&lt;p&gt;You can’t build a great product until you’ve built 52 bad ones.* If you only do
an iteration every month, then you are looking at 4.3 years to get to good. If
you do an iteration every week, then it only takes 1 year.&lt;&#x2F;p&gt;
&lt;p&gt;So instead of pining away about how can I possibly build a good iteration every
week, quit worrying about building a perfect release, and instead focus on
getting through the bad ones as quickly as possible.&lt;&#x2F;p&gt;
&lt;p&gt;This is a parody on Jonathan Stark’s
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jonathanstark.com&#x2F;daily&#x2F;20250512-1745-weekly-vs-daily&quot;&gt;“Weekly vs. Daily”&lt;&#x2F;a&gt;
post.&lt;&#x2F;p&gt;
&lt;p&gt;* This may be an exaggeration, but if we are honest with ourselves, it is often
astounding how many revisions it takes to get something working, let alone
great.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Who are users?</title>
        <published>2025-06-03T00:00:00+00:00</published>
        <updated>2025-06-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0179-who-are-users/"/>
        <id>https://bec-systems.com/blog/0179-who-are-users/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0179-who-are-users/">&lt;p&gt;To get really valuable feedback, we need users. If the product has not been
released yet, find someone – external CI system, CEO, beta users, manufacturing
people, accountants, your mom …&lt;&#x2F;p&gt;
&lt;p&gt;Often, when it leaves the developer’s computer, we find it does not even build,
let alone run and do something useful!&lt;&#x2F;p&gt;
&lt;p&gt;A user is &lt;strong&gt;&lt;em&gt;anyone&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; other than the developer.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>♻️ How to define an iteration?</title>
        <published>2025-06-02T00:00:00+00:00</published>
        <updated>2025-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0178-how-to-define-an-iteration/"/>
        <id>https://bec-systems.com/blog/0178-how-to-define-an-iteration/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0178-how-to-define-an-iteration/">&lt;p&gt;I’ve found it useful to define an iteration as a formal release (software that
is packaged and users use, a PCB that you build, a prototype, a web app that you
deploy, etc.). You don’t learn many things until you build and, more
importantly, others use - even if your users are only internal. Practice formal
releases during development, and then the process will be polished when you go
into production.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧑‍💻 How can we increase developer productivity?</title>
        <published>2025-05-29T00:00:00+00:00</published>
        <updated>2025-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0177-how-can-we-increase-developer-productivity/"/>
        <id>https://bec-systems.com/blog/0177-how-can-we-increase-developer-productivity/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0177-how-can-we-increase-developer-productivity/">&lt;blockquote&gt;
&lt;p&gt;“The way you get programmer productivity is not by increasing the lines of
code per programmer per day. That doesn’t work. The way you get programmer
productivity is by eliminating lines of code you have to write.The line of
code that’s the fastest to write, that never breaks, that doesn’t need
maintenance, is the line you never had to write.” –
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;3LEXae1j6EY&quot;&gt;Apple WWDC ’97 Steve Jobs Closing Keynote&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;How can we reduce the lines of code we need to write? Several ways come to mind:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use OSS components&lt;&#x2F;li&gt;
&lt;li&gt;Build on someone else’s platform&lt;&#x2F;li&gt;
&lt;li&gt;Don’t implement “just-in-case” features&lt;&#x2F;li&gt;
&lt;li&gt;Removed unused code (linting tools can find this for you)&lt;&#x2F;li&gt;
&lt;li&gt;Don’t implement unnecessary abstractions&lt;&#x2F;li&gt;
&lt;li&gt;Simplify&lt;&#x2F;li&gt;
&lt;li&gt;Reuse what you have already done (YOUR Platform)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 What is the quickest way to store and track data?</title>
        <published>2025-05-28T00:00:00+00:00</published>
        <updated>2025-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0176-what-is-the-quickest-way-to-store-and-track-data/"/>
        <id>https://bec-systems.com/blog/0176-what-is-the-quickest-way-to-store-and-track-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0176-what-is-the-quickest-way-to-store-and-track-data/">&lt;p&gt;Do you need a quick way to track some data? Serial numbers, part numbers, test
results, defect metrics, etc.?&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways, but one of the quickest and most flexible is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Comma-separated_values&quot;&gt;CSV&lt;&#x2F;a&gt; files in Gitea. You
are already using
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git*&lt;&#x2F;a&gt;,
right?&lt;&#x2F;p&gt;
&lt;p&gt;With CSV files in Gitea, you can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;View the data as a table&lt;&#x2F;li&gt;
&lt;li&gt;Easily edit the data using a variety of tools (Libreoffice, Gitea web UI,
etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Track and review changes&lt;&#x2F;li&gt;
&lt;li&gt;Manage access&#x2F;permissions&lt;&#x2F;li&gt;
&lt;li&gt;Work in a distributed fashion&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, it is easy to add automation to CSV files in Go or Python. While
databases can be very useful for larger datasets, they are often overkill for a
lot of things today, as most datasets (especially human-generated ones) now
easily fit in memory. And when it comes time to use a database, it is easy to
import your existing CSV data into a database.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌱 OSS can decrease or increase your code liability</title>
        <published>2025-05-27T00:00:00+00:00</published>
        <updated>2025-05-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0175-oss-can-decrease-or-increase-your-code-liability/"/>
        <id>https://bec-systems.com/blog/0175-oss-can-decrease-or-increase-your-code-liability/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0175-oss-can-decrease-or-increase-your-code-liability/">&lt;p&gt;A wise person
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;stettix&#x2F;5bb2d99e50fdbbd15dd9622837d14e2b&quot;&gt;once said&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Code is a liability, not an asset. Aim to have as little of it as possible.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Whether the open-source code in your projects is an asset or a liability depends
on how you handle it. Almost all code in complex systems
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0008-the-long-game&#x2F;&quot;&gt;needs to be maintained&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you do not update the OSS code in your projects, you are essentially
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;039&#x2F;&quot;&gt;forking it&lt;&#x2F;a&gt;, and it is now “your code” and you own it.
It is a static entity that is not gaining value unless you put direct effort
into it. Additionally, there will likely be issues that you now need to solve.
Very few OSS project maintainers are going to be interested in helping you fix a
problem in a 5-year-old snapshot.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, if you keep the OSS code in your projects up-to-date, then many
issues automatically get fixed (security, compatibility, performance, bugs, new
features, etc.). Additionally, if there is a problem, then maintainers will
likely work with you to fix it. In this scenario, OSS code is an asset – it is
gaining much more value than your direct effort. However, you must commit to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;updating OSS components regularly&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;having an automated way to comprehensively test the system&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;engage with the OSS projects you use, build relationships, and contribute
where you can (documentation and bug reports are contributions)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some effort is required on your part – it’s not a free lunch. However, if you
do this right, the benefit-cost ratio (BCR) is high –
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;daily.himvis.com&#x2F;0169-open-source-mindset-is-for-long-term&#x2F;&quot;&gt;well worth it in the long term&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝🔍 Trust, but verify</title>
        <published>2025-05-23T00:00:00+00:00</published>
        <updated>2025-05-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0174-trust-but-verify/"/>
        <id>https://bec-systems.com/blog/0174-trust-but-verify/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0174-trust-but-verify/">&lt;p&gt;Apparently, this is an
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;who-said-trust-but-verify-dm_2ZmH1RTG70CFTUjcNlA&quot;&gt;old Russian proverb that Ronald Reagan popularized&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is good general advice in life – don’t automatically distrust people and
go looking for problems, but when something does not look or feel right, verify.&lt;&#x2F;p&gt;
&lt;p&gt;As engineers, when we are building something new, this is important.&lt;&#x2F;p&gt;
&lt;p&gt;✅ Are our assumptions correct?&lt;&#x2F;p&gt;
&lt;p&gt;✅ Have we checked the edge conditions?&lt;&#x2F;p&gt;
&lt;p&gt;✅ Did this change break anything else?&lt;&#x2F;p&gt;
&lt;p&gt;✅ What are we missing?&lt;&#x2F;p&gt;
&lt;p&gt;As systems become more complex, two tools come to mind:&lt;&#x2F;p&gt;
&lt;p&gt;▶ Simulation (a faster&#x2F;cheaper way to verify)&lt;&#x2F;p&gt;
&lt;p&gt;▶ Automation (testing, deployment, etc. – do things humans don’t have time
for)&lt;&#x2F;p&gt;
&lt;p&gt;In complex systems, blind trust does not get us very far, especially in
ourselves. As engineers, the work we should verify the most is our own.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌽 What is the easiest way to avoid silos?</title>
        <published>2025-05-21T00:00:00+00:00</published>
        <updated>2025-05-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0173-what-is-the-easiest-way-to-avoid-silos/"/>
        <id>https://bec-systems.com/blog/0173-what-is-the-easiest-way-to-avoid-silos/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0173-what-is-the-easiest-way-to-avoid-silos/">&lt;p&gt;Silos occur when a person or group of people operate in isolation from the rest
of the organization. One of the reasons you have failure in organizations is one
silo does not know that the other silo is doing.&lt;&#x2F;p&gt;
&lt;p&gt;Silos are deadly in our organizations. How can we avoid them? The efficient way
is to use open, transparent, and common systems where possible for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Issue&#x2F;project tracking&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;tlsl01uxUfE&quot;&gt;Part number management&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Information storage (design files should be versioned in Git)&lt;&#x2F;li&gt;
&lt;li&gt;Releases&lt;&#x2F;li&gt;
&lt;li&gt;Change control and review (Pull requests)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;handbook.tmpdir.org&#x2F;documentation.html&quot;&gt;Documentation&lt;&#x2F;a&gt; (Markdown,
CSV, etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Software developers build really good workflow tools. Why, because they can
build their OWN tools. For this reason, no matter what your discipline, I
recommend starting with
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git*&lt;&#x2F;a&gt;.
For small teams, this can get you most of the way there. For larger teams, you
may need something more comprehensive like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.odoo.com&#x2F;&quot;&gt;odoo&lt;&#x2F;a&gt;. But,
start small with Git*, cover the basics, and add more complex systems when
needed.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤖 The biggest problem with AI</title>
        <published>2025-05-20T00:00:00+00:00</published>
        <updated>2025-05-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0172-the-biggest-problem-with-ai/"/>
        <id>https://bec-systems.com/blog/0172-the-biggest-problem-with-ai/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0172-the-biggest-problem-with-ai/">&lt;blockquote&gt;
&lt;p&gt;“It ain’t what you don’t know that gets you into trouble. It’s what you know
for sure that just ain’t so.” - Mark Twain (maybe)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;AI is really good at summarizing existing information. It is less good at
thinking, although it can do some amazing things. The biggest deficiency I see
right now is AI does not know how to ask questions and doesn’t know what it
doesn’t know. It just makes assumptions and pretends like it knows what it is
doing. People like this are some of the hardest ones to work with. They act like
they know everything and never think they are wrong. Smart people, blind to
their own weaknesses, make the subtlest, hardest problems to find.&lt;&#x2F;p&gt;
&lt;p&gt;Until AI is self-aware of its own weaknesses and knows how to ask questions, we
cannot fully trust it to operate like a professional human. It needs watched
very carefully. AI can still be very useful, and it will likely get better, but
for now, I think this is the current state.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤖 What is AI good for?</title>
        <published>2025-05-19T00:00:00+00:00</published>
        <updated>2025-05-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0171-what-ai-is-good-for/"/>
        <id>https://bec-systems.com/blog/0171-what-ai-is-good-for/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0171-what-ai-is-good-for/">&lt;p&gt;AI is really good at summarizing existing information – Perplexity Pro mostly
has replaced Google&#x2F;Duckduckgo, etc., and is worth every penny. AI is really
good at finding API documentation – much quicker than searching through docs,
and often provides a useful snippet of how to use an API. Occasionally, I’ll use
AI to write a quick Python script where I don’t care how it works.&lt;&#x2F;p&gt;
&lt;p&gt;The most useful scenario is when you are having an intelligent back-and-forth
conversation with AI, and you understand what is going on. What does not work is
just lazily expecting it to do all your work so you don’t have to understand it
– especially the hard parts like architecture. If AI is doing things that you
don’t understand, ask it to teach you. Write tests so you can be sure it is
right. Trust, but verify.&lt;&#x2F;p&gt;
&lt;p&gt;I’m currently working on a project with a smart intern working on the frontend
code. He is working fast and appears to be vibe coding some of it. Some of it is
a bit of a mess, but it mostly works. Some parts have obviously never even been
tested. Is vibe coding in this case a net gain? Probably, but I’m not sure yet
– will know more once we try to maintain this code.&lt;&#x2F;p&gt;
&lt;p&gt;On a project that is complex enough to require some architecture,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;coding-should-be-a-vibe-50908f49&quot;&gt;coding is not the hard part&lt;&#x2F;a&gt;.
Architecture, requirements, integration, testing, debugging, support … all
this stuff that is required to get it right swamps any coding effort. As
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;stettix&#x2F;5bb2d99e50fdbbd15dd9622837d14e2b&quot;&gt;one person said&lt;&#x2F;a&gt;,
“Code is a liability, not an asset. Aim to have as little of it as possible.”&lt;&#x2F;p&gt;
&lt;p&gt;At this point, don’t aim to have AI write all your code for you. Use AI to help
you write better code faster that YOU understand.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 What is my process for capturing experience? (part 3)</title>
        <published>2025-05-16T00:00:00+00:00</published>
        <updated>2025-05-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0170-what-is-my-process-for-capturing-experience-part-3/"/>
        <id>https://bec-systems.com/blog/0170-what-is-my-process-for-capturing-experience-part-3/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0170-what-is-my-process-for-capturing-experience-part-3/">&lt;p&gt;Reflection is another important aspect of the experience capture process. Do we
carefully evaluate and critically think about what happened? We don’t do this to
blame ourselves or others, but rather to recognize areas where we might improve.
Reflection can also include recognizing things that went well and what we need
to keep doing.&lt;&#x2F;p&gt;
&lt;p&gt;Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Personally spend 5m journalling at the end of each day. What went well? What
did not? What are we thankful for?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sre.google&#x2F;sre-book&#x2F;postmortem-culture&#x2F;&quot;&gt;Blameless postmortems&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Periodic project review – what have we learned? Is what we learned captured?&lt;&#x2F;li&gt;
&lt;li&gt;Pull requests – have we captured everything we have learned when we did this
work? Are there documentation and tests so the work can be extended and
reused?&lt;&#x2F;li&gt;
&lt;li&gt;Look for opportunities to automate. Automation is one of the best ways to
capture experience.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If we do not reflect, we are destined to keep repeating the same mistakes and
needlessly doing the same work over and over.&lt;&#x2F;p&gt;
&lt;p&gt;One of the most tragic and common forms of human nature is to just keep doing
what we are doing, even if it is not working.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 What is my process for capturing experience? (part 2)</title>
        <published>2025-05-15T00:00:00+00:00</published>
        <updated>2025-05-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0169-what-is-my-process-for-capturing-experience-part-2/"/>
        <id>https://bec-systems.com/blog/0169-what-is-my-process-for-capturing-experience-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0169-what-is-my-process-for-capturing-experience-part-2/">&lt;p&gt;In
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0168-what-is-my-process-for-capturing-experience&#x2F;&quot;&gt;part 1&lt;&#x2F;a&gt;,
we discussed the importance of getting information into permanent mediums. Below
are a some that I use:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Workflowy. This is my 2nd brain with 1000’s of notes, links, howtos, etc. It
is easy to share Workflowy notes with others as needed and multiple people can
collaborate on a note with just a link – no account needed. I can’t recommend
Workflowy enough – it is so flexible and powerful.&lt;&#x2F;li&gt;
&lt;li&gt;Checklists&lt;&#x2F;li&gt;
&lt;li&gt;Templates (typically a Google Doc)&lt;&#x2F;li&gt;
&lt;li&gt;OSS projects
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&quot;&gt;Github&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&quot;&gt;Simple IoT&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&quot;&gt;Yoe Distro&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&quot;&gt;GitPLM&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;&quot;&gt;My daily newsletter&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;&quot;&gt;TMPDIR Community Forum&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;&quot;&gt;TMPDIR Podcast&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;excalidraw-collaborative-whiteboarding-made-easy&#x2F;1058&#x2F;3?u=cbrake&quot;&gt;Sketches&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Youtube
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@cliffbrake&quot;&gt;General&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@simple-iot&quot;&gt;SimpleIoT&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@yoedistro&quot;&gt;Yoe Distro&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Automation (Ansible, scripts, CI, CD, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I try to not directly email useful information if possible, but rather write it
down somewhere permanent and then share the link.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 What is my process for capturing experience?</title>
        <published>2025-05-14T00:00:00+00:00</published>
        <updated>2025-05-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0168-what-is-my-process-for-capturing-experience/"/>
        <id>https://bec-systems.com/blog/0168-what-is-my-process-for-capturing-experience/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0168-what-is-my-process-for-capturing-experience/">&lt;p&gt;After
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0167-how-to-leverage-experience&#x2F;&quot;&gt;yesterday’s post&lt;&#x2F;a&gt;,
I was asked: “What’s your process to capture experience?”&lt;&#x2F;p&gt;
&lt;p&gt;The most important thing is to get information out of transient mediums into
permanent mediums.&lt;&#x2F;p&gt;
&lt;p&gt;What are the attributes of a permanent medium?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Searchable&lt;&#x2F;li&gt;
&lt;li&gt;Persistent (exists over time, backed up)&lt;&#x2F;li&gt;
&lt;li&gt;Easily accessible to all relevant parties over time, even those who join late&lt;&#x2F;li&gt;
&lt;li&gt;Well organized&lt;&#x2F;li&gt;
&lt;li&gt;Has context&lt;&#x2F;li&gt;
&lt;li&gt;Improved over time&lt;&#x2F;li&gt;
&lt;li&gt;Turned into automation where possible&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first two attributes are the easiest. While email, chat, and meetings are
useful in teams for communication and notifications, they are NOT permanent
mediums for information. Even though they may be persistent and searchable, they
fail on the other attributes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧠 How to leverage experience?</title>
        <published>2025-05-13T00:00:00+00:00</published>
        <updated>2025-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0167-how-to-leverage-experience/"/>
        <id>https://bec-systems.com/blog/0167-how-to-leverage-experience/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0167-how-to-leverage-experience/">&lt;p&gt;To leverage experience, we need to capture it. And to capture it, we need
process. Without this, leveraging the experience of our best people is at best
random. If we can capture experience, then we have it forever, even when our
best people inevitably move on.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔭 How to encourage vision?</title>
        <published>2025-05-09T00:00:00+00:00</published>
        <updated>2025-05-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0166-how-to-encourage-vision/"/>
        <id>https://bec-systems.com/blog/0166-how-to-encourage-vision/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0166-how-to-encourage-vision/">&lt;p&gt;Innovation is fueled by vision. Without vision, things can be directionless,
drifting toward obscurity. So, how to encourage vision? Perhaps the first thing
is not to discourage it. Ironically, the more successful an organization is, the
more likely this is to happen. This happens when people mistakenly confuse
experience with vision. In the realm of technology, how things were done
yesterday, while a useful guide and foundation, will not get us to where we need
to go tomorrow.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧠🔭 The tension of experience and vision</title>
        <published>2025-05-08T00:00:00+00:00</published>
        <updated>2025-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0165-the-tension-of-experience-and-vision/"/>
        <id>https://bec-systems.com/blog/0165-the-tension-of-experience-and-vision/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0165-the-tension-of-experience-and-vision/">&lt;p&gt;🧠 &lt;strong&gt;Experience&lt;&#x2F;strong&gt;: Guardrails for our journey, temperament for our actions.&lt;&#x2F;p&gt;
&lt;p&gt;🔭 &lt;strong&gt;Vision&lt;&#x2F;strong&gt;: The view of where we are going, the source of energy and
enthusiasm for our enterprise.&lt;&#x2F;p&gt;
&lt;p&gt;Experience is negative, a restraint. Vision is positive, a motivator. Both are
necessary in the right balance.&lt;&#x2F;p&gt;
&lt;p&gt;Again, dysfunction ensues when we mix these up.&lt;&#x2F;p&gt;
&lt;p&gt;Guardrails based purely on what we think will happen (vision) are not very
effective.&lt;&#x2F;p&gt;
&lt;p&gt;Building a product only on what has worked in the past (experience) is not very
compelling.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛣️ Two approaches to life</title>
        <published>2025-05-07T00:00:00+00:00</published>
        <updated>2025-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0164-two-approaches-to-life/"/>
        <id>https://bec-systems.com/blog/0164-two-approaches-to-life/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0164-two-approaches-to-life/">&lt;p&gt;There are two ways we can approach life:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Take responsibility and try to solve some of our own problems.&lt;&#x2F;li&gt;
&lt;li&gt;Expect others to solve all of our problems.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Owning the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0046-your-platform-vs-others&#x2F;&quot;&gt;integration points&lt;&#x2F;a&gt;
in our product vs. outsourcing everything.&lt;&#x2F;li&gt;
&lt;li&gt;Critically evaluate what we hear vs. blind trust.&lt;&#x2F;li&gt;
&lt;li&gt;Growing&#x2F;raising some of our food vs. buying all of it.&lt;&#x2F;li&gt;
&lt;li&gt;Learning to find fulfillment in doing vs. allowing others to fulfill us by
entertaining.&lt;&#x2F;li&gt;
&lt;li&gt;Making&#x2F;building some of what we need vs. buying everything.&lt;&#x2F;li&gt;
&lt;li&gt;Running Arch Linux on our computers, where we control the system vs. an OS
vendor.&lt;&#x2F;li&gt;
&lt;li&gt;Proactively learning about nutrition and health vs. total dependence on
mainstream medicine.&lt;&#x2F;li&gt;
&lt;li&gt;Owning YOUR Platform vs. expecting someone else’s platform to solve all our
needs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the short term, the first approach rarely makes business sense. However,
long-term, we learn that the second approach is an illusion.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏆 The entire story</title>
        <published>2025-05-06T00:00:00+00:00</published>
        <updated>2025-05-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0163-the-entire-story/"/>
        <id>https://bec-systems.com/blog/0163-the-entire-story/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0163-the-entire-story/">&lt;p&gt;In debates about technology, people
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;linux&#x2F;comments&#x2F;1ka5xyb&#x2F;am_i_crazy_or_is_arch_linux_the_easiest_distro_to&#x2F;&quot;&gt;bring up points&lt;&#x2F;a&gt;,
such as an Arch Linux update occasionally breaking and not booting; thus, Arch
Linux is bad.&lt;&#x2F;p&gt;
&lt;p&gt;While the above point is true, it is also irrelevant because it is not the
entire story. What about:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The hours upon hours I’ve saved updating and installing stuff because pacman
is so fast.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The 100’s of packaged tools and applications that save me from installing them
manually.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The AUR, which has everything that is not already packaged, making it easy to
install even the most obscure piece of software.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The benefits of using the latest and best versions of everything. After all,
if something is getting better, may as well benefit from it now vs later.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The simplicity of PKGBUILD, which allows me to create and modify my own
packages easily.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I could go on, but you get the point. After running Arch for over 10 years,
let’s conservatively say I’ve saved an hour a week by using Arch – that is 520
hours. I’ve spent maybe 5 hours working through broken stuff in Arch in 10
years. That is a benefit-cost ratio (BCR) of 104. So yes, the 5 hours are real,
but they are irrelevant.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👤 It&#x27;s all about the people</title>
        <published>2025-05-05T00:00:00+00:00</published>
        <updated>2025-05-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0162-it-s-all-about-the-people/"/>
        <id>https://bec-systems.com/blog/0162-it-s-all-about-the-people/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0162-it-s-all-about-the-people/">&lt;p&gt;It is very true, we need great people in our organizations. And I have the
utmost respect for those who can motivate and lead people. I also have the
utmost respect for the capabilities of humans – that divine spark of creativity
and the ability of the human brain to solve problems and make new connections.&lt;&#x2F;p&gt;
&lt;p&gt;However, to do much in this age requires people to work together and build on
the work of the past. What one person does, another person needs to continue.
The lone accomplishments of any one individual may be impressive, but without
continuity and scale, there is likely to be very little lasting impact. Without
systems in place (YOUR Platform), the brilliant work of your people will not be
utilized to their full potential.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧠🔭 Experience and Vision</title>
        <published>2025-04-29T00:00:00+00:00</published>
        <updated>2025-04-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0161-experience-and-vision/"/>
        <id>https://bec-systems.com/blog/0161-experience-and-vision/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0161-experience-and-vision/">&lt;p&gt;In the realm of product development, there are two powerful forces – experience
and vision.&lt;&#x2F;p&gt;
&lt;p&gt;Experience (the past) is a guide – a help to avoid serious blunders and
mistakes. Experience can help us avoid dead-end tangents. Experience gives us a
gut feel that is critical at times. Experience helps us be more efficient if we
can make fewer mistakes.&lt;&#x2F;p&gt;
&lt;p&gt;Vision (the future) is where we are going. It is seeing things that have not
been done before. It is exploring new combinations of technology to build
compelling products. It is adopting new technology, including tools, software,
components, and workflows. It is about understanding the needs of your
customers.&lt;&#x2F;p&gt;
&lt;p&gt;Without experience, we are on the path to collapse.&lt;&#x2F;p&gt;
&lt;p&gt;Without vision, we are on the path to obscurity.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📊 Past performance ...</title>
        <published>2025-04-28T00:00:00+00:00</published>
        <updated>2025-04-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0160-past-performance/"/>
        <id>https://bec-systems.com/blog/0160-past-performance/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0160-past-performance/">&lt;blockquote&gt;
&lt;p&gt;“past performance is not indicative of future results”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The above phrase is a disclaimer we often see associated with investments.&lt;&#x2F;p&gt;
&lt;p&gt;However, this applies to more than investments …&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A technology that was cutting edge in the past may not be the best option for
the future (example building web applications in PHP vs Go).&lt;&#x2F;li&gt;
&lt;li&gt;People who did good work in the past usually continue to do good work, but not
always. (people can lose interest, suffer burnout, have personal problems,
etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Workflows used in the past are not always the best option for the future
(example, requiring patches on mail-lists will probably alienate a significant
portion of the developer population who were raised on pull-requests).&lt;&#x2F;li&gt;
&lt;li&gt;As the level of integration in integrated circuits continues, the IC we used
in the past may not be the best solution compared to more integrated solutions
available in the future.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;How we proceed in the future needs to be a combination of what we learned in the
past (experience) and the technology available in the future (vision). Again,
dysfunction arises when we mix these two modes up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✔️ Legacy code</title>
        <published>2025-04-25T00:00:00+00:00</published>
        <updated>2025-04-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0159-legacy-code/"/>
        <id>https://bec-systems.com/blog/0159-legacy-code/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0159-legacy-code/">&lt;p&gt;Michael Feathers defines legacy code as code without tests. He further
elaborates in
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;library&#x2F;view&#x2F;working-effectively-with&#x2F;0131177052&#x2F;&quot;&gt;his book&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Code without tests is bad code. It doesn’t matter how well written it is; it
doesn’t matter how pretty or object-oriented or how well-encapsulated it is.
With tests, we can change the behavior of our code quickly and verifiably.
Without them, we really don’t know if our code is getting better or worse.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Without automated tests, any modification to the codebase is risky, as there is
no reliable way to know if a change introduces defects. This lack of feedback
forces us to rely on manual testing or institutional knowledge – often lost
over time – which makes maintenance difficult and error-prone. It is not about
the age of the code or who wrote it, but about whether the code can be changed
safely. If you cannot verify behavior through tests, the code is “legacy”
regardless of its age or origin.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Git driven CD -- you know what got deployed</title>
        <published>2025-04-24T00:00:00+00:00</published>
        <updated>2025-04-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0158-git-driven-cd-you-know-what-got-deployed/"/>
        <id>https://bec-systems.com/blog/0158-git-driven-cd-you-know-what-got-deployed/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0158-git-driven-cd-you-know-what-got-deployed/">&lt;p&gt;Git driven CD (Continuous Deployment) typically means whenever you merge to
&lt;code&gt;main&lt;&#x2F;code&gt; , or tag a repo, something automatically gets deployed. It can be
something as simple as a static website being updated.&lt;&#x2F;p&gt;
&lt;p&gt;One of the biggest advantages to this is that you know for sure the code was
checked in and tagged. And you know exactly what code was deployed. There is no
manual process involved to mess it up.&lt;&#x2F;p&gt;
&lt;p&gt;This may not seem like a big deal, but it is. As humans, we get lazy and forget
to do the simple things like manually tagging a repo – especially on small
teams where process is not emphasized. However, CD is a way to have a process
without having a process. You do it in the name of saving time, but it also
gives you enough process that things are now also consistent.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💸 Technical debt</title>
        <published>2025-04-23T00:00:00+00:00</published>
        <updated>2025-04-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0157-technical-debt/"/>
        <id>https://bec-systems.com/blog/0157-technical-debt/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0157-technical-debt/">&lt;p&gt;I like the definition of technical debt from
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;seths.blog&#x2F;2025&#x2F;04&#x2F;technical-debt-and-ai-slop&#x2F;&quot;&gt;this article:&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Technical debt is anything that slows down your ability to update and upgrade
your work&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ Another reason to self-host Gitea</title>
        <published>2025-04-22T00:00:00+00:00</published>
        <updated>2025-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0156-another-reason-to-self-host-gitea/"/>
        <id>https://bec-systems.com/blog/0156-another-reason-to-self-host-gitea/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0156-another-reason-to-self-host-gitea/">&lt;p&gt;You own your data – forever. You don’t need to keep paying monthly fees if you
decide to switch to a different system just to access your historical data and
conversations.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve been advocating that development discussions should happen in
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0149-git-the-new-standard-for-workflow&#x2F;&quot;&gt;Git*&lt;&#x2F;a&gt;
issues&#x2F;PRs&#x2F;projects whenever possible, so the conversations have context. One
requirement for this to work long term is that you need access to these
conversations for the duration of a product, and perhaps beyond.&lt;&#x2F;p&gt;
&lt;p&gt;There is a hosting cost, but it is minimal ($5&#x2F;mo on a Linode server). There is
also some ops cost to keep things running and up to date, but in my experience,
Gitea is cake to self-host compared to things like WordPress or Email. The
benefit-to-effort ratio is huge.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👷 The tension between solo and collaborative work</title>
        <published>2025-04-21T00:00:00+00:00</published>
        <updated>2025-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0155-the-tension-between-solo-and-collaborative-work/"/>
        <id>https://bec-systems.com/blog/0155-the-tension-between-solo-and-collaborative-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0155-the-tension-between-solo-and-collaborative-work/">&lt;p&gt;As systems become more complex, we emphasize collaboration more and more. But we
must also remember that truth is still largely a solo pursuit. Truth by
committee is almost an oxymoron. The new algorithms, the keen insights, and the
disruptive inventions are usually not the work of a committee, but rather a lone
person exploring the boundaries of knowledge, careful observation, and making
new connections from what already exists. And really, invention is not anything
new, but rather a discovery of the universal truths that exist in our universe
– the laws of nature.&lt;&#x2F;p&gt;
&lt;p&gt;Increasingly, we need to be good at both – the focus and solitude required for
deep work, and the collaboration required to build complex systems. The great
ideas will generally come from the former, but the ability to do anything useful
with them requires the latter.&lt;&#x2F;p&gt;
&lt;p&gt;Dysfunction arises when we mix these two modes up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🕹️ What can we control?</title>
        <published>2025-04-18T00:00:00+00:00</published>
        <updated>2025-04-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0154-what-can-we-control/"/>
        <id>https://bec-systems.com/blog/0154-what-can-we-control/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0154-what-can-we-control/">&lt;p&gt;There are some things we can control:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Products have a robust field update mechanism.&lt;&#x2F;li&gt;
&lt;li&gt;Automated testing is in place.&lt;&#x2F;li&gt;
&lt;li&gt;We have automated deployments.&lt;&#x2F;li&gt;
&lt;li&gt;We have processes to quickly and confidently make and release hardware
changes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And some things we can’t control:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A customer asking for a new feature we did not anticipate.&lt;&#x2F;li&gt;
&lt;li&gt;Bugs showing up in the field.&lt;&#x2F;li&gt;
&lt;li&gt;Security problems in a dependency.&lt;&#x2F;li&gt;
&lt;li&gt;Cloud vendor infrastructure problems.&lt;&#x2F;li&gt;
&lt;li&gt;Supply chain issues (have we forgotten COVID already)?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But if we do the first list, then we are prepared to handle the second. However,
we tend to focus most of our energy on the 2nd list (onerous contracts with
vendors, extensive manual testing of the “final” release, etc.) and think we are
controlling the situation, when in reality we are not – it’s just an illusion.
Really, it is change that we fear, as change is associated with a lack of
control. But it is change that gives us control.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😩 Boring, error-prone, repetitive, tedious work</title>
        <published>2025-04-17T00:00:00+00:00</published>
        <updated>2025-04-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0153-boring-error-prone-repetitive-tedious-work/"/>
        <id>https://bec-systems.com/blog/0153-boring-error-prone-repetitive-tedious-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0153-boring-error-prone-repetitive-tedious-work/">&lt;p&gt;Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;manually testing software&lt;&#x2F;li&gt;
&lt;li&gt;manually constructing a bill of materials&lt;&#x2F;li&gt;
&lt;li&gt;searching your email for some bit of information&lt;&#x2F;li&gt;
&lt;li&gt;scrolling through logs looking for potential problems&lt;&#x2F;li&gt;
&lt;li&gt;manually configuring a new server&lt;&#x2F;li&gt;
&lt;li&gt;manually deploying software updates&lt;&#x2F;li&gt;
&lt;li&gt;manually checking for spacing violations in a PCB layout&lt;&#x2F;li&gt;
&lt;li&gt;building physical prototype circuits and trying a range of different
components&lt;&#x2F;li&gt;
&lt;li&gt;organizing parts or physical materials without an easy way to identify or sort
them&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If this describes what we are doing, there may be an opportunity for workflow or
automation improvements. This is the kind of work computers do best – to free
us up for what humans do best.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧑‍💻 Will AI cause coding to disappear?</title>
        <published>2025-04-16T00:00:00+00:00</published>
        <updated>2025-04-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0152-will-ai-cause-coding-to-disappear/"/>
        <id>https://bec-systems.com/blog/0152-will-ai-cause-coding-to-disappear/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0152-will-ai-cause-coding-to-disappear/">&lt;p&gt;AI is not a binary off&#x2F;on thing, like many of the industry commentators like to
think. Many of us are already using AI to improve our productivity. For me,
Perplexity has largely replaced Google search.&lt;&#x2F;p&gt;
&lt;p&gt;Technology has always brought productivity gains: ASM -&amp;gt; C -&amp;gt; Code generators -&amp;gt;
Libraries -&amp;gt; OSS -&amp;gt; Google search -&amp;gt; Zephyr -&amp;gt; etc. AI is just another step.&lt;&#x2F;p&gt;
&lt;p&gt;Coding has always been the easy part. Requirements, innovation, collaboration,
architecture, integration, debugging, etc. – these are the hard parts. There
will always be a place for skilled humans … people with intuition, creativity,
experience, taste, vision, and style. People who see and can do what does not
already exist.&lt;&#x2F;p&gt;
&lt;p&gt;If all you do is translate well-defined requirements into code, then yeah, I’d
be worried. However, there is a lot more that needs to be done that is of much
higher value, and not enough people to do it. Step up!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Survey of device ID mechanisms</title>
        <published>2025-04-15T00:00:00+00:00</published>
        <updated>2025-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2417/survey-of-device-id-mechanisms/"/>
        <id>https://bec-systems.com/2417/survey-of-device-id-mechanisms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2417/survey-of-device-id-mechanisms/">&lt;p&gt;Are you implementing an IoT system that requires you to identify many connected devices? This post reviews different types of IDs and provides some technical details to help you decide if any of these are appropriate for your application.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-14.png&quot; alt=&quot;&quot; style=&quot;width:343px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Note: some of the below information was generated by Perplexity and may not be 100% accurate. The goal of this article is to get a sense of all the different types of IDs in use. To implement anything, use the official documentation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;uuids&quot;&gt;UUIDs&lt;&#x2F;h2&gt;
&lt;p&gt;UUIDs (Universally Unique Identifiers) are often used in distributed software systems where multiple distributed systems create objects that must be uniquely identified. UUIDs are typically 128-bit numbers represented in a 36-character format that might look like: d50ae174-b65f-4ab9-b938-5f99b67ac50b. Base64 encoded UUIDs can be as short as 22 characters and look like: 1QrhdLZfSrm5OF-ZtnrFCw. UUIDs are typically constructed using the time and the MAC address of the device generating the UUID.&lt;&#x2F;p&gt;
&lt;p&gt;These IDs are attractive because no central organization or database is required to prevent conflicts - they can be created anywhere at will with a statistically insignificant possibility that there will ever be a collision. However, these IDs are large and best processed by machines, not humans.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mac-address-eui-48&quot;&gt;MAC Address&#x2F;EUI-48&lt;&#x2F;h2&gt;
&lt;p&gt;Network devices use a MAC (Media Access Control) address, also called (EUI-48), to uniquely identify a device on a network. These are 48-bit numbers typically displayed as 12 hexadecimal digits and grouped into 6 pairs (&lt;code&gt;00:1A:2B:3C:4D:5E&lt;&#x2F;code&gt;). The first half of the MAC address is called the OUI (Organizationally Unique Identifier). &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;standards.ieee.org&#x2F;products-programs&#x2F;regauth&#x2F;&quot;&gt;IEEE is the registration authority&lt;&#x2F;a&gt; for MAC address blocks. You can purchase 4K, 1M, and 16M size blocks; the cost ranges from $1,080 to $3,680 at the time of writing.&lt;&#x2F;p&gt;
&lt;p&gt;You can also purchase EEPROM integrated circuits, like the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;en-us&#x2F;product&#x2F;24AA02E48&quot;&gt;24AA02E48&lt;&#x2F;a&gt; from Microchip, that have a EUI-48 number already programmed into it. This is a nice option for lower volume products where you don’t want to mess around with managing the EUI-48 numbers.&lt;&#x2F;p&gt;
&lt;p&gt;One advantage of using a MAC address is that it may already be programmed into the device you are using, so it does not require any extra effort to allocate and program the ID.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bluetooth-low-energy-ble&quot;&gt;Bluetooth Low Energy (BLE)&lt;&#x2F;h2&gt;
&lt;p&gt;BLE uses “MAC” (EUI-48) hardware addresses from the same pool as Ethernet. Additionally, the following IDs are used:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table class=&quot;has-fixed-layout&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Identifier Type&lt;&#x2F;th&gt;&lt;th&gt;Size&lt;&#x2F;th&gt;&lt;th&gt;Purpose&#x2F;Usage&lt;&#x2F;th&gt;&lt;th&gt;Example&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Bluetooth Address (EUI-48)&lt;&#x2F;td&gt;&lt;td&gt;48 bits&lt;&#x2F;td&gt;&lt;td&gt;Device-level unique ID (public or random)&lt;&#x2F;td&gt;&lt;td&gt;12:34:56:78:9A:BC&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;UUID (16&#x2F;32&#x2F;128-bit)&lt;&#x2F;td&gt;&lt;td&gt;16&#x2F;32&#x2F;128b&lt;&#x2F;td&gt;&lt;td&gt;Service&#x2F;characteristic identification&lt;&#x2F;td&gt;&lt;td&gt;0x180D, 12345678-...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Company Identifier&lt;&#x2F;td&gt;&lt;td&gt;16 bits&lt;&#x2F;td&gt;&lt;td&gt;Manufacturer&#x2F;vendor identification&lt;&#x2F;td&gt;&lt;td&gt;0x004C (Apple)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;System ID (Device Info)&lt;&#x2F;td&gt;&lt;td&gt;64 bits&lt;&#x2F;td&gt;&lt;td&gt;Encodes device&#x27;s MAC address (optional)&lt;&#x2F;td&gt;&lt;td&gt;(varies)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Local Name&lt;&#x2F;td&gt;&lt;td&gt;Variable&lt;&#x2F;td&gt;&lt;td&gt;Human-readable device name&lt;&#x2F;td&gt;&lt;td&gt;&quot;Charge HR&quot;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Appearance&#x2F;Class Codes&lt;&#x2F;td&gt;&lt;td&gt;16 bits&lt;&#x2F;td&gt;&lt;td&gt;Device type&#x2F;classification&lt;&#x2F;td&gt;&lt;td&gt;0x0340 (Heart Rate Sensor)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;bluetooth-mesh&quot;&gt;Bluetooth Mesh&lt;&#x2F;h2&gt;
&lt;p&gt;Bluetooth Mesh networking introduces several unique identifiers (IDs) at various layers of the protocol to manage devices, messages, and network security. These IDs serve different purposes than traditional Bluetooth or BLE device addresses.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unicast Address (Node Address&#x2F;Element Address)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Each node (device) in a Bluetooth Mesh network is assigned a unique &lt;strong&gt;unicast address&lt;&#x2F;strong&gt; during the provisioning process. This is a 16-bit value that uniquely identifies the node or its elements within the mesh network.&lt;&#x2F;li&gt;
&lt;li&gt;A node can have multiple elements, each with its own unicast address in a contiguous range.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Group Address&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;16-bit values used to address multiple nodes simultaneously (e.g., all lights in a room). Nodes can subscribe to one or more group addresses, enabling efficient publish&#x2F;subscribe communication.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Virtual Address&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;128-bit values derived from a UUID. They allow addressing of a logical group of nodes, regardless of their physical location or provisioning sequence. Virtual addresses are mapped to a 16-bit address space for use in messages.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device Key (DevKey)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A unique 128-bit cryptographic key assigned to each node during provisioning. It is used for secure communication between the provisioner and the node, especially for configuration and management messages.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Network Key (NetKey) and Application Key (AppKey)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Network Keys&lt;&#x2F;strong&gt; are shared among all nodes in a mesh network and are used to secure network layer messages.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Application Keys&lt;&#x2F;strong&gt; are used to secure application-specific messages, allowing for separation of different functionalities (e.g., lighting vs. sensor data).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Model Identifier&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Each mesh model (defining device behavior, such as a light switch or sensor) is assigned a unique identifier:&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;SIG-adopted models&lt;&#x2F;strong&gt;: Identified by a 16-bit model identifier.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Vendor-specific models&lt;&#x2F;strong&gt;: Identified by a 16-bit vendor ID and a 16-bit model ID.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Message Sequence Number&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Every message sent by a node includes a &lt;strong&gt;sequence number&lt;&#x2F;strong&gt; to prevent replay attacks and ensure message uniqueness.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device Property ID&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For sensor and property models, each property (e.g., temperature, humidity) is assigned a unique &lt;strong&gt;Device Property ID&lt;&#x2F;strong&gt; as per the Bluetooth Mesh device properties specification.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Node ID&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Some documentation refers to a &lt;strong&gt;Node ID&lt;&#x2F;strong&gt; (or nodeId), typically a 2-byte value, as a unique identifier for a mesh device within the network, used for addressing and control.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;ipv6-eui-64&quot;&gt;IPv6&#x2F;EUI-64&lt;&#x2F;h2&gt;
&lt;p&gt;IPv6&#x2F;EUI-64 addresses are a 64-bit number commonly used in IPv6 and typically displayed as 8 groups of four hexadecimal digits: &lt;code&gt;2001:0db8:85a3:0000:0000:8a2e:0370:7334&lt;&#x2F;code&gt;. Consecutive groups of zeros can be replaced with a double colon. For example, &lt;code&gt;2001:0db8:0000:0000:0000:0000:0000:0001&lt;&#x2F;code&gt; can be shorted to &lt;code&gt;2001:0db8::1&lt;&#x2F;code&gt;. Note, leading zeros in the group are also omitted. IPv6 address blocks are assigned by the Internet Assigned Numbers Authority (IANA), which allocates large blocks of addresses to Regional Internet Registries (RIRs). These RIRs then distribute smaller blocks to Internet Service Providers (ISPs) and other organizations. The ARIN (American Registry for Internet Numbers) provides blocks of IPv6 addresses. The annual fee for a 3X-Small block (288 addresses) is $262.50 at the time of writing.&lt;&#x2F;p&gt;
&lt;p&gt;There are also EEPROM and other ICs that have EUI-64 numbers preprogrammed, such as the Microchip &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;en-us&#x2F;product&#x2F;24AA02E64&quot;&gt;24AA02E64&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qr-codes&quot;&gt;QR Codes&lt;&#x2F;h2&gt;
&lt;p&gt;QR codes provide the opportunity to easily read a UUIDs or some other long ID on every device using a phone camera. This relieves some of the complexity of humans having to deal with long IDs.&lt;&#x2F;p&gt;
&lt;p&gt;Entering a known device in the field into an application is easy with QR codes. However, finding a device (one among many) in the field can be difficult unless the application has a feature designed just for this.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-13.png&quot; alt=&quot;&quot; style=&quot;width:392px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There is no central registry for QR codes. Instead, the process of QR code generation and use is decentralized and relies on the vast number of possible QR code combinations to avoid conflicts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;snmp-private-enterprise-numbers-pen&quot;&gt;SNMP&#x2F;Private Enterprise Numbers (PEN)&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;strong&gt;SNMP Private Enterprise Number (PEN)&lt;&#x2F;strong&gt; is a unique identifier assigned by the Internet Assigned Numbers Authority (IANA) to organizations, individuals, or entities. It is primarily used in network management protocols like Simple Network Management Protocol (SNMP) to identify objects defined by an enterprise within the Management Information Base (MIB) structure.&lt;&#x2F;p&gt;
&lt;p&gt;PENs are part of the Object Identifier (OID) hierarchy under the prefix &lt;code&gt;1.3.6.1.4.1&lt;&#x2F;code&gt;, which corresponds to &lt;code&gt;.iso.org.dod.internet.private.enterprise&lt;&#x2F;code&gt;. This prefix ensures that each PEN is globally unique.&lt;&#x2F;p&gt;
&lt;p&gt;Any entity can request a PEN assignment &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;enterprise-numbers&#x2F;&quot;&gt;from IANA at no cost&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;automobile-vin&quot;&gt;Automobile VIN&lt;&#x2F;h2&gt;
&lt;p&gt;The modern 17-character Vehicle Identification Number (VIN) format was first conceptualized and standardized by the United States National Highway Traffic Safety Administration (NHTSA) in 1981. This standardization aimed to unify the previously inconsistent vehicle identification practices across manufacturers and facilitate more effective tracking of recalls, registrations, and thefts. The VIN system introduced by NHTSA was later adopted globally and is now governed by the International Organization for Standardization (ISO), specifically under ISO 3779 (content and structure) and ISO 4030 (location and attachment)&lt;&#x2F;p&gt;
&lt;p&gt;An example of an automobile VIN (Vehicle Identification Number) is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1P8ZA1279SZ215470&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;VINs are always 17 characters long and use a combination of capital letters and digits. Each section of the VIN provides specific information about the vehicle:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The first three characters (World Manufacturer Identifier) indicate the manufacturer and country of origin.&lt;&#x2F;li&gt;
&lt;li&gt;Characters 4–8 describe features such as model, body type, and engine.&lt;&#x2F;li&gt;
&lt;li&gt;The 9th character is a check digit for security.&lt;&#x2F;li&gt;
&lt;li&gt;The 10th character indicates the model year (e.g., “S” for 1995, “R” for 1994 or 2024).&lt;&#x2F;li&gt;
&lt;li&gt;The 11th character shows the assembly plant.&lt;&#x2F;li&gt;
&lt;li&gt;The last six characters are a unique serial number for that vehicle.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;knx-serial-number&quot;&gt;KNX Serial Number&lt;&#x2F;h2&gt;
&lt;p&gt;KNX is a popular building automation standard. The KNX &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;support.knx.org&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;4641703241234-KNX-Serial-Number&quot;&gt;serial numbers&lt;&#x2F;a&gt; follow the following format:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Length:&lt;&#x2F;strong&gt; The KNX serial number is always 6 bytes (octets) long.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manufacturer Code:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Octets 6 and 5&lt;&#x2F;strong&gt; (the first two bytes, when read from left to right) contain the official KNX Manufacturer Code assigned to each manufacturer by the KNX Association.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device-Specific Portion:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Octets 4 to 1&lt;&#x2F;strong&gt; (the remaining four bytes) are managed by the manufacturer.&lt;&#x2F;li&gt;
&lt;li&gt;This part may encode information such as production site, date, series, batch, or simply a sequential unique number.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;bacnet&quot;&gt;BACnet&lt;&#x2F;h2&gt;
&lt;p&gt;BACnet Device IDs, also known as Device Object Identifiers or Device Instance Numbers, are unique numerical values assigned to each BACnet device on a network to identify them distinctly.&lt;&#x2F;p&gt;
&lt;p&gt;The Device ID is a 22-bit unsigned integer ranging from 0 to 4,194,302 (decimal). The value 4,194,303 (0x3FFFFF) is reserved and cannot be used as a valid Device ID.&lt;&#x2F;p&gt;
&lt;p&gt;This Device ID corresponds to the object instance number portion of the BACnet Device Object’s Object_Identifier property.&lt;&#x2F;p&gt;
&lt;p&gt;The full Object_Identifier is a 32-bit value composed of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Object Type (10 bits): For a Device object, this is fixed as 8.&lt;&#x2F;li&gt;
&lt;li&gt;Object Instance (22 bits): The Device ID itself.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;BACnet IDs are not assigned during manufacturing, but rather during setup&#x2F;installation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;matter&quot;&gt;Matter&lt;&#x2F;h2&gt;
&lt;p&gt;Matter devices include a Device Attestation Certificate (DACs) generated through a hierarchical Public Key Infrastructure (PKI) process, ensuring each device is uniquely authenticated. Each device is cryptographically verified, making spoofing difficult.&lt;&#x2F;p&gt;
&lt;p&gt;The DAC is part of a chain of trust:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Product Attestation Authority (PAA):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Root certificate issued by the Connectivity Standards Alliance (CSA) or an approved third party.&lt;&#x2F;li&gt;
&lt;li&gt;Stored in the Distributed Compliance Ledger (DCL), a global registry of trusted certificates.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Product Attestation Intermediate (PAI):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Intermediate certificate signed by the PAA.&lt;&#x2F;li&gt;
&lt;li&gt;Typically includes the manufacturer’s Vendor ID (VID).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device Attestation Certificate (DAC):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unique per-device certificate signed by the PAI.&lt;&#x2F;li&gt;
&lt;li&gt;Contains the device’s VID, Product ID (PID), public key, and serial number.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Additionally, devices use rotating keys, which makes tracking difficult and preserves privacy. End users scan a QR code to onboard devices.&lt;&#x2F;p&gt;
&lt;p&gt;Matter attempts to be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Authentic (not counterfeit)&lt;&#x2F;li&gt;
&lt;li&gt;Secure (resistant to hacking)&lt;&#x2F;li&gt;
&lt;li&gt;Private (resistant to tracking)&lt;&#x2F;li&gt;
&lt;li&gt;Interoperable (works with any ecosystem)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;serial-numbers&quot;&gt;Serial Numbers&lt;&#x2F;h2&gt;
&lt;p&gt;Other custom serial numbers take many different forms. Some examples are shown below:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table class=&quot;has-fixed-layout&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Format Type&lt;&#x2F;th&gt;&lt;th&gt;Example&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;th&gt;Typical Use Cases&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Sequential&lt;&#x2F;td&gt;&lt;td&gt;D000001&lt;&#x2F;td&gt;&lt;td&gt;Incremented by one, often padded with zeros&lt;&#x2F;td&gt;&lt;td&gt;Manufacturing, inventory&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Alphanumeric&lt;&#x2F;td&gt;&lt;td&gt;TBL-101A234&lt;&#x2F;td&gt;&lt;td&gt;Letters and numbers, often with category or model encoded&lt;&#x2F;td&gt;&lt;td&gt;Electronics, equipment rental&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Random&lt;&#x2F;td&gt;&lt;td&gt;X9F4-7T32-ZY6&lt;&#x2F;td&gt;&lt;td&gt;Unpredictable, generated by algorithm&lt;&#x2F;td&gt;&lt;td&gt;Security-sensitive items&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Date&#x2F;Batch Embedded&lt;&#x2F;td&gt;&lt;td&gt;20230715-001-123&lt;&#x2F;td&gt;&lt;td&gt;Encodes date and batch with sequence number&lt;&#x2F;td&gt;&lt;td&gt;Quality control, traceability&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;systemd-network-interfaces&quot;&gt;Systemd network interfaces&lt;&#x2F;h2&gt;
&lt;p&gt;Systemd’s predictable network interface name encodes the physical path of the device. Example of how &lt;strong&gt;enp0s13f0u2c2&lt;&#x2F;strong&gt; is constructed:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;en&lt;&#x2F;strong&gt;: Ethernet device (prefix for Ethernet interfaces).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;p0&lt;&#x2F;strong&gt;: PCI bus 0&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;s13&lt;&#x2F;strong&gt;: PCI slot 13 (device 13 on the bus)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;f0&lt;&#x2F;strong&gt;: PCI function 0&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;u2&lt;&#x2F;strong&gt;: USB port 2 (the device is connected via USB, possibly a USB Ethernet adapter)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;c2&lt;&#x2F;strong&gt;: USB configuration or child port 2 (sometimes used to indicate a specific port or configuration on a USB hub)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;I’m sure there are many other examples – please leave a comment if you’d like to share other interesting formats. In a future post, we’ll explore a new standard for device IDs that is optimized for human interaction in the field. Subscribe below to stay informed of the latest developments.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✅ Guarantees</title>
        <published>2025-04-15T00:00:00+00:00</published>
        <updated>2025-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0151-guarantees/"/>
        <id>https://bec-systems.com/blog/0151-guarantees/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0151-guarantees/">&lt;p&gt;Sometimes we want guarantees:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Are you sure this will work?&lt;&#x2F;li&gt;
&lt;li&gt;Can we lock this down to a rock-solid stable release?&lt;&#x2F;li&gt;
&lt;li&gt;Is it fully tested?&lt;&#x2F;li&gt;
&lt;li&gt;Will this vendor be able to provide this part forever?&lt;&#x2F;li&gt;
&lt;li&gt;Do we have all the features the product will ever need?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The reality is that in complex systems, nothing is guaranteed. There will be
problems, especially during integration and new use scenarios. No supplier is
guaranteed. We can’t anticipate all the use cases of a complex system.&lt;&#x2F;p&gt;
&lt;p&gt;So the more important questions are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Can we start integration and testing earlier?&lt;&#x2F;li&gt;
&lt;li&gt;Do we have automated testing?&lt;&#x2F;li&gt;
&lt;li&gt;Can we easily update deployed systems?&lt;&#x2F;li&gt;
&lt;li&gt;Can we pivot to new components as required?&lt;&#x2F;li&gt;
&lt;li&gt;Do we have processes and workflows in place to quickly and confidently make
any needed changes (hardware or software)?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 The 2nd key to effective process</title>
        <published>2025-04-14T00:00:00+00:00</published>
        <updated>2025-04-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0150-the-2nd-secret-to-effective-processes/"/>
        <id>https://bec-systems.com/blog/0150-the-2nd-secret-to-effective-processes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0150-the-2nd-secret-to-effective-processes/">&lt;p&gt;If the people at the top don’t use the process, hardly anyone else will either.
What we do often speaks way louder than what we say.&lt;&#x2F;p&gt;
&lt;p&gt;(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0140-the-secret-to-process&#x2F;&quot;&gt;1st key …&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ Git* -- the new standard for workflow</title>
        <published>2025-04-11T00:00:00+00:00</published>
        <updated>2025-04-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0149-git-the-new-standard-for-workflow/"/>
        <id>https://bec-systems.com/blog/0149-git-the-new-standard-for-workflow/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0149-git-the-new-standard-for-workflow/">&lt;p&gt;It started with Github, a place to host your OSS projects. Over time, several
other options emerged, and each has its place:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;&quot;&gt;Github&lt;&#x2F;a&gt;: excellent for OSS projects where you want to
attract the most developers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;&quot;&gt;Gitlab&lt;&#x2F;a&gt;: great for a large hosted enterprise solution.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.gitea.com&#x2F;&quot;&gt;Gitea&lt;&#x2F;a&gt;: a great solution for small&#x2F;midsize teams
building products. Can be run on a $5&#x2F;mo Linode or Digital Ocean cloud server.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;forgejo.org&#x2F;&quot;&gt;Forgejo&lt;&#x2F;a&gt;: is a fork of Gitea focused more on community
and security.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’ll call the above &lt;strong&gt;Git*&lt;&#x2F;strong&gt;. These tools set a new standard for workflow
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0148-the-defining-characteristic-of-a-good-workflow-tool&#x2F;&quot;&gt;integration&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ The defining characteristic of a good workflow tool</title>
        <published>2025-04-10T00:00:00+00:00</published>
        <updated>2025-04-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0148-the-defining-characteristic-of-a-good-workflow-tool/"/>
        <id>https://bec-systems.com/blog/0148-the-defining-characteristic-of-a-good-workflow-tool/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0148-the-defining-characteristic-of-a-good-workflow-tool/">&lt;p&gt;As mentioned in the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0147-the-critical-features-of-workflow-tools&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt;,
modern workflow tools provide efficient access to information, collaboration,
and automation.&lt;&#x2F;p&gt;
&lt;p&gt;The real power is when these &lt;strong&gt;three things come together&lt;&#x2F;strong&gt; in one environment.
The defining characteristic of a good workflow tool is … &lt;strong&gt;integration&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There are powerful project board tools like Jira or Trello. There are great
communication tools like Discourse, Discord, Slack, and Email. There are popular
code review tools like Gerrit. But good things happen when you bring all these
things together into one workflow tool, which I will call Git*: Github, Gitlab,
Gitea, or Forgejo. Then everything has context, and relationships between
different types of information are easy to create. Integration in a tool is a
powerful thing where the overall value is much greater than the sum of the
individual features.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ The critical features of workflow tools</title>
        <published>2025-04-09T00:00:00+00:00</published>
        <updated>2025-04-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0147-the-critical-features-of-workflow-tools/"/>
        <id>https://bec-systems.com/blog/0147-the-critical-features-of-workflow-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0147-the-critical-features-of-workflow-tools/">&lt;p&gt;Tools are what enable knowledge work in the information age. Several critical
features:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Efficient access to information&lt;&#x2F;li&gt;
&lt;li&gt;Collaboration&lt;&#x2F;li&gt;
&lt;li&gt;Automation&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We’ll discuss more in the future posts …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to implement Zephyr web applications</title>
        <published>2025-04-08T00:00:00+00:00</published>
        <updated>2025-04-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2420/how-to-implement-zephyr-web-applications/"/>
        <id>https://bec-systems.com/2420/how-to-implement-zephyr-web-applications/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2420/how-to-implement-zephyr-web-applications/">&lt;p&gt;Are you considering implementing a web UI in your &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zephyrproject.org&#x2F;&quot;&gt;Zephyr RTOS&lt;&#x2F;a&gt; application and perplexed by the endless number of web technologies available today? This article traces my journey through trying several options and presents some of the tradeoffs.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-10.png&quot; alt=&quot;&quot; style=&quot;width:377px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Modern microcontrollers (MCUs) have many connectivity options (Ethernet, WiFi, Bluetooth, Cellular, etc.), and when coupled with the Zephyr OS, implementing a web application on these devices often makes sense. Once you start doing this, you soon realize that this is not Ruby-on-Rails. Rather, Zephyr is still a very constrained environment (see my &lt;a href=&quot;&#x2F;1540&#x2F;microcontroller-mcu-or-microprocessor-mpu&#x2F;&quot;&gt;article on the differences between MPUs and MCUs&lt;&#x2F;a&gt;). While we can still leverage modern web technologies, we need to be selective because of the constraints of MCU systems. An example of a web UI in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-siot&#x2F;tree&#x2F;main&#x2F;apps&#x2F;siot-net&quot;&gt;Zephyr SimpleIoT project&lt;&#x2F;a&gt; is shown below:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;primary-concerns-in-an-mcu-system&quot;&gt;Primary concerns in an MCU system&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;size&quot;&gt;Size&lt;&#x2F;h2&gt;
&lt;p&gt;The memory resources on MCU and MPU systems are &lt;a href=&quot;&#x2F;1540&#x2F;microcontroller-mcu-or-microprocessor-mpu&#x2F;&quot;&gt;vastly different&lt;&#x2F;a&gt; – a difference of over 1,000x.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table class=&quot;has-fixed-layout&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;MCU (Internal)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;MCU (External)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;MPU (Server)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Flash&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;0.5-2MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;16MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;500GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;RAM&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;0.25 - 1MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;16MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;16GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;While it is possible to use larger memory devices with MCUs, like an SD card or SDRAM, the above table is for the more common scenarios.&lt;&#x2F;p&gt;
&lt;p&gt;If we want to serve the web application entirely from a Zephyr device, then the web assets must fit in flash. The RAM size also limits the number of connections we can handle and the size of the data payloads we can transmit and receive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stability-includes-maintainability-and-security&quot;&gt;&lt;strong&gt;Stability (includes maintainability and security)&lt;&#x2F;strong&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The constraints of an MCU drive us toward doing more in the browser (frontend) because resources there are free and plentiful. This typically ends up being a Single-Page Application (SPA) architecture, where the web application is a free-running application that fetches and sends data to the MCU (backend). All rendering happens in the browser instead of the MCU. Because of this, the web application needs to be stable. Extra care must be taken so that the application does not crash and freeze or pop up annoying messages telling the user to reload the page, which can easily happen with JavaScript.&lt;&#x2F;p&gt;
&lt;p&gt;We also need to consider how the application is hosted. A typical web application is hosted in the cloud in one place. If there is a problem, we have complete control over updating and fixing it as needed. Embedded applications are a completely different matter – there may be thousands of devices. If there are problems, it is not as simple as updating a single server. We may have a firmware update mechanism in the device, but it is often up to the user to decide when to update. Users expect embedded devices to be stable. Many of them are used in critical applications. An instability in the web UI of the device does not give a positive impression, even though it may only be a web frontend crash, and the device is still functioning fine.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:600px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;It seems simple to write an initial prototype, but maintaining a web application over time is a different matter. Security can also be a concern as many web frameworks pull in mountains of JavaScript dependencies via NPM, which are difficult to audit for security problems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;state-management&quot;&gt;&lt;strong&gt;State Management&lt;&#x2F;strong&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;One of the hardest parts of a web application is maintaining state. The reason for this is that user interfaces can be deeply nested and complex. The naive approach is to distribute the state into each UI component. The difficulty with this is keeping everything in sync. There has been a continual stream of new frontend state management libraries (Redux, MobX, VueX, React Context, XState, react-easy-state, etc.). This is not an easy problem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;options&quot;&gt;Options&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;serve-site-assets-from-external-server&quot;&gt;Serve site&#x2F;assets from external server&lt;&#x2F;h2&gt;
&lt;p&gt;One way to work around the asset size constraint in MCUs is to serve large assets (like a Bootstrap CSS file) from an external server.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-2.png&quot; alt=&quot;&quot; style=&quot;width:375px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There are several potential issues with this:&lt;&#x2F;p&gt;
&lt;p&gt;❌ The external asset must always be available, and if it goes away or changes, then the web application on the device must be updated to point to the new location.&lt;&#x2F;p&gt;
&lt;p&gt;❌ If the entire site is served from an external server, then you must host all versions of the web application or be very careful to maintain backward compatibility to all previous versions of firmware running on the Zephyr device.&lt;&#x2F;p&gt;
&lt;p&gt;❌ You may need the Zephyr UI to function if the Internet is down or unavailable (example: air-gapped secure setups or during device setup). In many systems, device state is mirrored to an upstream server, so the only time you would use the local UI is during setup or when the Internet is down.&lt;&#x2F;p&gt;
&lt;p&gt;✅ &lt;strong&gt;The most reliable way to host a Zephyr web application is on the device itself.&lt;&#x2F;strong&gt; You certainly have many more options if you host it externally, but there are tradeoffs that must be considered.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;no-build-just-html-js-css&quot;&gt;No Build, just HTML, JS, CSS&lt;&#x2F;h2&gt;
&lt;p&gt;DHH and others are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;once-1-is-entirely-nobuild-for-the-front-end-ce56f6d7&quot;&gt;advocating No-Build&lt;&#x2F;a&gt; web solutions. However, they have Rails for a backend, and we have Zephyr. I investigated this approach, but manually mutating HTML elements in JavaScript in a complex app is messy and scattered – you’ll eventually create a framework anyway, so you may as well start with something close to meeting your needs.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-6.png&quot; alt=&quot;&quot; style=&quot;width:400px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;HTML&#x2F;JS&#x2F;CSS development is powerful and flexible, but is tailored to design, not programming. In its raw state, it is like developing a program where everything is a global variable. If you have a dynamic web application responding to real-world events, this quickly becomes a programming problem that is difficult to manage with 200 global variables. You need an abstraction on top of this. Again, a powerful templating engine on the backend helps a lot, which we do not have in Zephyr applications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;react-vue-angular-non-compiled-frameworks&quot;&gt;React, Vue, Angular (non-compiled frameworks)&lt;&#x2F;h2&gt;
&lt;p&gt;Solutions like React are too large for many MCU applications as they typically require a megabyte or more of web assets to be transferred from the host. Additionally, you have the issue of JavaScript crashes and the continual bloat and churn of the NPM package ecosystem. Updating to new versions of packages can be a lot of work as APIs sometimes change. While this solution can work for large-scale cloud-hosted apps, it is not ideal for embedded web UIs where you often don’t have control over the device and can’t easily patch the system if there is a problem.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-12.png&quot; alt=&quot;&quot; style=&quot;width:420px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;I’ve been writing&#x2F;maintaining a 50K SLOC Meteor&#x2F;React app for the past 10 years – it works and has been very successful. However, we’ve had a handful of frontend crashes. Being a cloud app, we were able to deploy fixes for this quickly, but it is still an inconvenience for users. In another project developed by a very experienced JavaScript developer, we also had a number of JavaScript crashes in the frontend. There are likely ways to reduce or avoid these stability problems, but it is not inherent in the system&#x2F;language. It requires a high degree of carefulness and discipline. It is not easy to refactor JavaScript and know that you have fixed all the issues caused by your code change.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-11.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There are slimmer solutions like Preact which may solve the size issue, but you likely lose some of the integration with all the libraries written for React.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;htmx&quot;&gt;htmx&lt;&#x2F;h2&gt;
&lt;p&gt;htmx is the cool kid on the block right now – supposedly simple and easy to use. I tried this for the first iteration of a Zephyr web application and got a prototype running, but concluded it works best if you have a powerful backend that can do most of your rendering, and the frontend just handles a little bit of reactivity. Additionally, with htmx, you typically open up a network connection for every widget to get updates, and this requires a lot of connection resources on the backend, which are expensive in a Zephyr system.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-7.png&quot; alt=&quot;&quot; style=&quot;width:313px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;svelte&quot;&gt;Svelte&lt;&#x2F;h2&gt;
&lt;p&gt;Svelte is a compiled language that generates small assets, so it works well from a size perspective. It also appears to be a well-maintained project with good tooling. However, there are two downsides: 1) it is still JavaScript, so you have potential stability issues when maintaining applications long-term. 2) It puts the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;free-code-camp&#x2F;react-s-jsx-the-other-side-of-the-coin-2ace7ab62b98#.rvo6p4jsq&quot;&gt;“JS” in the “HTML” instead of the “HTML” in the “JS”&lt;&#x2F;a&gt; (like React or Elm). This is largely a matter of preference, but as a programmer, I prefer the latter. The success of React indicates that many others do, too.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;functional-languages&quot;&gt;Functional Languages&lt;&#x2F;h2&gt;
&lt;p&gt;Functional languages are becoming more common in frontend development because they solve many reliability and refactoring challenges. Some options include ClojureScript, Elm (discussed below), PureScript, ReasonML, F#, Scala.js. Some of these options likely have smaller asset sizes than non-compiled options.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elm&quot;&gt;Elm&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elm-lang.org&#x2F;&quot;&gt;Elm&lt;&#x2F;a&gt; is a compiled language that produces small assets. It is like React JSX in that it &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;free-code-camp&#x2F;react-s-jsx-the-other-side-of-the-coin-2ace7ab62b98#.rvo6p4jsq&quot;&gt;puts the “HTML” in the “Elm&lt;&#x2F;a&gt;“. Elm is a functional language that solves many of the challenges with web programming, including stability and managing state. Runtime errors in an Elm application are very rare. I wrote the Simple IoT UI in Elm, which is now 18,610 lines of code, and have maintained it since 2018. It has never crashed, and it is easy to add new features. Code density&#x2F;reuse in Elm is very high. If it compiles, it generally works, so very little time is spent in the browser console debugging stuff. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mdgriffith&#x2F;elm-ui&quot;&gt;elm-ui&lt;&#x2F;a&gt; package offers a powerful style and layout system that eliminates most of the pain with web programming and allows someone (like me) who is not a dedicated web developer to maintain a pretty nice web application without learning the intricacies of CSS.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-9.png&quot; alt=&quot;&quot; style=&quot;width:279px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;As you maintain an Elm project, you’ll find that the language pushes you to a cleaner design. It nudges you in the right direction. The opposite generally happens in JavaScript projects, where a lot more discipline is required to keep things from becoming a mess.&lt;&#x2F;p&gt;
&lt;p&gt;Elm allows for creating powerful functions like the following for a text input form:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;textInput Point.typeBitRate &amp;quot;Bit rate&amp;quot; &amp;quot;250000&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This line of code renders a form element and automatically posts a new point to the backend of type &lt;code&gt;BitRate&lt;&#x2F;code&gt; when the content is changed, nothing else in the system needs to change for this to happen. There are no “handlers” that need to be attached to this element. Elm also has some of the best tooling in this industry – elm-review, elm-land, etc. This tooling is largely made possible by the language.&lt;&#x2F;p&gt;
&lt;p&gt;Elm is a small project and community, but it is a stable&#x2F;friendly community that has existed for many years, and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jah2488&#x2F;elm-companies&quot;&gt;many companies are successfully using Elm&lt;&#x2F;a&gt;. The Elm package system is fairly comprehensive and has most of what you might need to implement web apps. Since Elm packages are pure Elm, the entire ecosystem is stable and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;is-elm-considered-a-secure-lan-aAvNu0V6TfCAe4uVg9kXMw&quot;&gt;relatively secure&lt;&#x2F;a&gt;. There is some concern about the future of Elm as the compiler does not get frequent updates. Some have produced new versions of the compiler to meet special needs. The packages and tooling around Elm are where most innovation is happening right now, and it is phenomenal. Elm got it mostly right, so there is not much that needs immediate improvement in the core.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;There is no silver bullet in technology. With any choice, there are tradeoffs. Most people stick with mainstream JavaScript for frontend programming as the “safe” approach. However, in Zephyr&#x2F;MCU-based systems, there are constraints that we don’t face in server environments.&lt;&#x2F;p&gt;
&lt;p&gt;There are significant challenges in the HTML&#x2F;JS&#x2F;CSS world. While it is nice to have options, the continual churn of new frameworks (jQuery -&amp;gt; Backbone -&amp;gt; Ember -&amp;gt; Angular -&amp;gt; Meteor -&amp;gt; React -&amp;gt; Angular2 -&amp;gt; Vue -&amp;gt; Svelte -&amp;gt; Next.js) (and many others) indicates there is some fundamental problem with the Javacript approach that has not been solved in a general way. The number of NPM package dependencies pulled into a typical project is staggering and nearly impossible for small teams to audit for security and longevity. NPM installs routinely break for various reasons. NPM suffers from some of the same problems as Python, as many packages compile C code in non-standard ways during the package install process, which can be fragile.&lt;&#x2F;p&gt;
&lt;p&gt;There is also the issue of what might be viewed as an impedance mismatch – what the technology mega-companies produce and use is not always the best fit for small companies&#x2F;teams with limited resources. Facebook faces different problems on a different scale than a small embedded team. While React is right for them, we can’t assume it is right for everyone. Most of us are not facing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.bradfieldcs.com&#x2F;you-are-not-google-84912cf44afb&quot;&gt;Google-scale problems&lt;&#x2F;a&gt; that require a system as complex as Kubernetes. Ansible and a few servers work just fine. Facebook has near-infinite resources. They have ways to deal with the inherent stability problems of JavaScript. A small company&#x2F;team does not have these resources, so different technologies like Elm may be a better fit.&lt;&#x2F;p&gt;
&lt;p&gt;When faced with the need for a Zephyr web application, I tried htmx first, then looked at “no build”. Neither of these worked very well for me. Having worked on decent-sized React and Elm projects, Elm looked like a better fit for the next try due to asset size, reliability, and maintainability. Additionally, I had already solved the problem of how to effectively deal with &lt;a href=&quot;&#x2F;2432&#x2F;struggling-to-scale-your-iot-system-simplify-your-data&#x2F;&quot;&gt;data in a distributed IoT system&lt;&#x2F;a&gt;, and had &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;blob&#x2F;master&#x2F;frontend&#x2F;src&#x2F;UI&#x2F;NodeInputs.elm&quot;&gt;frontend code already written&lt;&#x2F;a&gt; to interface with this dataflow in Simple IoT. It was easy to port the Simple IoT frontend to a smaller version tailored for MCUs, and thus far it seems to be working well. Check out the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-siot&#x2F;tree&#x2F;main&#x2F;apps&#x2F;siot-net&quot;&gt;Simple IoT Zephyr Networking Example&lt;&#x2F;a&gt; to learn more.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✉️ Email filters</title>
        <published>2025-04-08T00:00:00+00:00</published>
        <updated>2025-04-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0146b-email-filters/"/>
        <id>https://bec-systems.com/blog/0146b-email-filters/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0146b-email-filters/">&lt;p&gt;Email is an amazing technology – the only widespread decentralized
communication tool we have. But most of us are flooded with email. The
fundamental problem is when we get emails from so many different sources,
projects, and contexts flowing into one inbox. The context switching as we go
from one email to the next is very expensive.&lt;&#x2F;p&gt;
&lt;p&gt;Email filters which automatically put emails into folders can help tame this
problem. Gmail already tries to do this automatically with their Primary,
Promotions, Social, and Updates. However, we can also do things like the
following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;filter emails for every project&#x2F;context into a separate folder. You can
trigger of senders, subject, etc.&lt;&#x2F;li&gt;
&lt;li&gt;filter notifications from workflow tools (Github, Trello, etc.) into folders.
If there are separate projects, then create separate folders for each project.&lt;&#x2F;li&gt;
&lt;li&gt;filter email newsletters into two folders: news-high-priority, and
news-low-priority – the former is the ones you want to read, and the latter
you just browse occasionally.&lt;&#x2F;li&gt;
&lt;li&gt;create a “personal” folder that emails outside of work get filtered into.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is automation that makes information easier to process. Of course some
emails will still slip into your inbox, but for most of our email, everything is
grouped into a single context. This greatly improves our efficiency in
processing them.&lt;&#x2F;p&gt;
&lt;p&gt;The critical thing is to use an email client that makes it easy to create
filters. Thunderbird &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;WZDpk73X5Vs&quot;&gt;works pretty well&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Everybody Works and the impact on meetings</title>
        <published>2025-04-07T00:00:00+00:00</published>
        <updated>2025-04-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0146-everybody-works/"/>
        <id>https://bec-systems.com/blog/0146-everybody-works/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0146-everybody-works/">&lt;p&gt;In a recent podcast titled
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;37signals.com&#x2F;podcast&#x2F;everybody-works&#x2F;&quot;&gt;Everybody Works&lt;&#x2F;a&gt;, the owners of
a 60-person company discuss the impact of full-time managers and one of them is
more meetings:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;And the primary problem with management is when it’s full time and it’s only
that it can’t do anything by itself. So the way 40 hours are manifested is
through other people. It’s, hey, can you join this meeting? Hey, can we do a
one-on-one? Hey, can we do some planning? Hey, can we do? Every bit of it is
something that pulls someone who’s actually working on things away from that
work and into the managerial orb. And I think we just finally came to the
realization we did not need that. We do not need that at our scale, that we
can supplement the work that we’re doing with a handful of managerial
practices or protocols, things that don’t even require human to run.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The following article also discusses the subject:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;we-once-more-have-no-full-time-managers-at-37signals-f8611085&quot;&gt;We once more have no full-time managers at 37signals&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Efficient meetings</title>
        <published>2025-04-04T00:00:00+00:00</published>
        <updated>2025-04-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0145-efficient-meetings/"/>
        <id>https://bec-systems.com/blog/0145-efficient-meetings/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0145-efficient-meetings/">&lt;p&gt;There are a lot of good ideas for effective meetings:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;seths.blog&#x2F;2018&#x2F;04&#x2F;whos-meeting-is-this-a-simple-checklist&#x2F;&quot;&gt;Whose meeting is this? A simple checklist&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nav.al&#x2F;who-has-time-for-meetings&quot;&gt;Who has time for meetings?&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are good reasons to have a meeting (hanging out, brainstorming, setting
priorities, making decisions), but in this age sharing information is probably
not one of them. People should have access to information before the meeting.
The goal of the meeting should also be known ahead of time. It is like planning
your day the night before — your subconscious has time to work on it and you are
prepared. Prepared people are efficient.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Meetings and human relationships</title>
        <published>2025-04-03T00:00:00+00:00</published>
        <updated>2025-04-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0144-meetings-and-personal-relationships/"/>
        <id>https://bec-systems.com/blog/0144-meetings-and-personal-relationships/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0144-meetings-and-personal-relationships/">&lt;p&gt;Improving human relationships is sometimes used as a justification for meetings,
and face-to-face meetings can certainly improve human relationships.&lt;&#x2F;p&gt;
&lt;p&gt;But more generally, we can say that positive interactions improve human
relationships. And the more positive interactions we have, the stronger our
relationships will be.&lt;&#x2F;p&gt;
&lt;p&gt;Modern workflow tools provide a tremendous opportunity for human interactions at
a scale that is impossible to accomplish with meetings. They provide
transparency. The stream of activity is visible to all, and anyone can
participate (or ignore) at any time. There are so many more opportunities for
positive interaction than a weekly, or even daily status meeting.&lt;&#x2F;p&gt;
&lt;p&gt;However, it is necessary to have a culture that encourages and promotes
transparency and frequent, positive interactions. It starts with the example of
those at the top. Do you provide positive feedback, give helpful suggestions,
and ask thoughtful questions in the course of work? Do you follow the
development activity and use the communication features of the workflow tools
such as Issue&#x2F;PRs&#x2F;project boards comments?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Why meetings?</title>
        <published>2025-04-02T00:00:00+00:00</published>
        <updated>2025-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0143-why-meetings/"/>
        <id>https://bec-systems.com/blog/0143-why-meetings/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0143-why-meetings/">&lt;p&gt;There are many reasons to call meetings:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Accountability&lt;&#x2F;li&gt;
&lt;li&gt;Knowledge transfer&lt;&#x2F;li&gt;
&lt;li&gt;Transparency&lt;&#x2F;li&gt;
&lt;li&gt;Status&lt;&#x2F;li&gt;
&lt;li&gt;Review&lt;&#x2F;li&gt;
&lt;li&gt;Oversight&lt;&#x2F;li&gt;
&lt;li&gt;Improve&#x2F;maintain relationships&lt;&#x2F;li&gt;
&lt;li&gt;Brainstorming&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;However, in this age of excellent collaboration tools (Git workflows, project
boards, etc.), meetings are an inefficient way to handle the first 6 items on
the above list. If our workflow does not provide complete transparency into what
everyone is doing, then there may be opportunities to improve our workflow.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Horizontal vs Vertical Scaling</title>
        <published>2025-04-01T00:00:00+00:00</published>
        <updated>2025-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0142-horizontal-vs-vertical-scaling/"/>
        <id>https://bec-systems.com/blog/0142-horizontal-vs-vertical-scaling/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0142-horizontal-vs-vertical-scaling/">&lt;p&gt;In the context of product development:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Horizontal Scaling&lt;&#x2F;strong&gt;: Selling more units, getting more customers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Vertical Scaling&lt;&#x2F;strong&gt;: Add value to already sold&#x2F;deployed units.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Bigger vs. Better – both are valid ways to scale and produce value. In this age
of powerful connected devices, vertical scaling is becoming increasingly
important. And that is where YOUR Platform matters.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👌 Struggling to scale your IoT system? Simplify your data.</title>
        <published>2025-03-31T00:00:00+00:00</published>
        <updated>2025-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0141-struggling-to-scale-your-iot-system-simplify-your-data/"/>
        <id>https://bec-systems.com/blog/0141-struggling-to-scale-your-iot-system-simplify-your-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0141-struggling-to-scale-your-iot-system-simplify-your-data/">&lt;p&gt;I recently published a new blog article about IoT data. Have you struggled with
adapting your IoT system to new applications and requirements? Is handling
configuration updates at both the cloud and edge a challenge? Is synchronizing
required data between cloud and edge instances a challenge? This article
describes a simple way to model data that eliminates many of these difficulties.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;2432&#x2F;struggling-to-scale-your-iot-system-simplify-your-data&#x2F;&quot;&gt;Read here …&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Struggling to scale your IoT system? Simplify your data.</title>
        <published>2025-03-29T00:00:00+00:00</published>
        <updated>2025-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2432/struggling-to-scale-your-iot-system-simplify-your-data/"/>
        <id>https://bec-systems.com/2432/struggling-to-scale-your-iot-system-simplify-your-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2432/struggling-to-scale-your-iot-system-simplify-your-data/">&lt;p&gt;Have you struggled with adapting your IoT system to new applications and requirements? Is handling configuration updates at both the cloud and edge a challenge? Is synchronizing required data between cloud and edge instances a challenge? This article describes a simple way to model data that eliminates many of these difficulties.&lt;&#x2F;p&gt;
&lt;p&gt;We can scale an IoT system both &lt;strong&gt;horizontally&lt;&#x2F;strong&gt; (deploy more units) and &lt;strong&gt;vertically&lt;&#x2F;strong&gt; (add features and address new applications). While the ideas presented in this essay are focused on vertical scale, any simplification will likely help with horizontal scale as well.&lt;&#x2F;p&gt;
&lt;p&gt;Previously, we explored &lt;a href=&quot;&#x2F;1884&#x2F;layered-event-and-data-centric-architectures-in-distributed-iot-systems&#x2F;&quot;&gt;data-centric architectures in IoT systems&lt;&#x2F;a&gt;. This post expands on this by describing how to represent data using Nodes and Points in a way that drastically simplifies IoT data storage, exchange, and synchronization. This is in contrast to encodings and mechanisms used in traditional web and cloud systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-are-iot-systems-different&quot;&gt;How are IoT systems different?&lt;&#x2F;h2&gt;
&lt;p&gt;IoT systems 🌐 have the following properties, which differentiate them from traditional computer&#x2F;web&#x2F;cloud applications:&lt;&#x2F;p&gt;
&lt;p&gt;🌐 IoT systems are inherently distributed (equipment is located in many physically different locations).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 Data must exist concurrently in multiple places (cloud and many edge instances).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 Data is not fully replicated on every instance (a cloud server instance might contain the entire dataset, whereas an edge instance only has a tiny fraction of the dataset that is relevant at that site).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 Instances are not symmetrical (edge instances are very different than cloud instances. It is not a cluster).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 There can be many instances (thousands of edge devices).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 The network is even less reliable (edge systems are often in uncontrolled environments).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 The system must continue to operate during network interruptions (it is not a cluster).&lt;&#x2F;p&gt;
&lt;p&gt;We can attempt to address these challenges by adding constraints such as: 1) data only flows in one direction, 2) device configuration is only changed in the cloud, and 3) the data payload format will not change over time. However, if we think realistically about these constraints, they are impractical for many systems. In distributed computer systems, change is the constant. Because a system can be networked, its capabilities are endless. The ability to connect to new and different systems means new systems and new value can always be created, and &lt;em&gt;&lt;strong&gt;things will change&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;. If you don’t, somebody else will.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-struct&quot;&gt;The &lt;em&gt;“struct”&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Cloud&#x2F;Web APIs have traditionally used various encoding schemes and patterns such as Protobuf, JSON, REST, gRPC, etc. Tools exist to manage schemas, such as GraphQL and JSON Schema. Synchronization mechanisms can be used to manage conflicts (Raft, CRDT, etc.). Most of these schemes assume that the complex &lt;em&gt;struct&lt;&#x2F;em&gt; with multiple and sometimes nested fields is the fundamental element of data representation, storage, and transmission. An example is shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;type EmployeeData struct {
    ID                 int
    Name               string
    Age                int
    Email              string
    Phone              string
    Street             string
    City               string
    Country            string
    PostalCode         string
    EmploymentHistory  []struct {
        Company  string
        Position string
        Years    int
    }
    Skills             map[string]struct {
        Proficiency     string
        YearsExperience int
    }
    LastUpdated        time.Time
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Structs are great – they are a powerful tool for organizing data in a computer program. They are so useful that we have also assumed structs are the best way to store and transfer data outside a program. Thus, we have tables in SQL databases, REST APIs, Protobuf&#x2F;JSON encoding, etc. This works fairly well and is likely the right solution in many domains. However, we have the following problems with using the &lt;code&gt;struct&lt;&#x2F;code&gt; outside a computer program:&lt;&#x2F;p&gt;
&lt;p&gt;❌ Updating the &lt;code&gt;struct&lt;&#x2F;code&gt; tends to be an all-or-nothing proposition. Fetching the data from a REST API gives you the entire &lt;code&gt;struct&lt;&#x2F;code&gt;. Likewise, when updating, you send the entire &lt;code&gt;struct&lt;&#x2F;code&gt;. There are tools, such as GraphQL, that attempt to solve this problem.&lt;&#x2F;p&gt;
&lt;p&gt;❌ Schema changes are painful. Many very elaborate tools are dedicated to solving the problem of database migrations.&lt;&#x2F;p&gt;
&lt;p&gt;❌ API schema changes are even more painful.&lt;&#x2F;p&gt;
&lt;p&gt;❌ Distributed systems are hard, especially if the &lt;code&gt;struct&lt;&#x2F;code&gt; may be updated by multiple systems concurrently and then requires merging. CRDTs and various other distributed system algorithms attempt to solve this problem, but they are complex.&lt;&#x2F;p&gt;
&lt;p&gt;❌ Nested data is problematic and compounds issues with schema changes and synchronization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-in-iot-systems&quot;&gt;Data in IoT Systems&lt;&#x2F;h2&gt;
&lt;p&gt;What are desirable features for handling data in a distributed IoT system?&lt;&#x2F;p&gt;
&lt;p&gt;✔️ We can generate&#x2F;change data anywhere (in the cloud, at the edge, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;✔️ Synchronization between instances is granular, simple, and reliable.&lt;&#x2F;p&gt;
&lt;p&gt;✔️ Data can flow in any direction.&lt;&#x2F;p&gt;
&lt;p&gt;✔️ One mechanism&#x2F;transport can be used for all types of data (config, sensor samples, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;✔️ All data changes in the system are recorded in history.&lt;&#x2F;p&gt;
&lt;p&gt;On the surface, this seems like a hard problem. If you have a &lt;em&gt;struct&lt;&#x2F;em&gt; that exists in multiple places, and one field gets changed in one location, and another field gets changed in a second location, how do you reconcile the differences and record what has changed?&lt;&#x2F;p&gt;
&lt;p&gt;As mentioned before, there are solutions such as CRDTs or sending data changes over the wire. Some systems only store changes (mutations) and then compute the current state from all the changes. However, all these schemes are mostly just adding layers of complexity on top of an existing paradigm and are rarely a good fit for IoT systems where you accumulate many thousands of data samples (changes) over time. Maybe it’s time to change the paradigm …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;points-and-nodes&quot;&gt;Points and Nodes&lt;&#x2F;h2&gt;
&lt;p&gt;What if we rethink our concept of data representation? Instead of trying to make a generic &lt;code&gt;struct&lt;&#x2F;code&gt; the fundamental unit of data, we take a more granular approach and focus on each piece of data in a struct. Can we create a simple unit of data that is easy to store and synchronize, and then build on top of this? This same unit of data is used for everything, including configuration, sample data, notifications, etc. The data unit we have arrived at in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;&quot;&gt;Simple IoT project&lt;&#x2F;a&gt; (after many iterations) is the “Point.”&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image-3.png&quot; alt=&quot;&quot; style=&quot;width:250px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The data type is typically a &lt;code&gt;string&lt;&#x2F;code&gt;, &lt;code&gt;int&lt;&#x2F;code&gt;, or &lt;code&gt;float&lt;&#x2F;code&gt;, but it can be anything you want.&lt;&#x2F;p&gt;
&lt;p&gt;Points are organized in a hierarchical tree of nodes, where each node contains an array of points.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:300px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Because a &lt;code&gt;point&lt;&#x2F;code&gt; is defined by both a &lt;code&gt;type&lt;&#x2F;code&gt; and a &lt;code&gt;key&lt;&#x2F;code&gt;, it is possible to construct arrays and maps by populating the &lt;code&gt;key&lt;&#x2F;code&gt; field with either an array index or a map key. This allows us to easily represent one level of structure (arrays and maps) in a node as shown in the following example:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image-6.png&quot; alt=&quot;&quot; style=&quot;width:600px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;If a deeper structure is required, then nest additional nodes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benefits&quot;&gt;Benefits&lt;&#x2F;h2&gt;
&lt;p&gt;There are multiple benefits to this data architecture.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Data is granular.&lt;&#x2F;strong&gt; An edge instance can update a node’s sensor reading, and the user can update a node’s config setting in the cloud simultaneously. The points are easily merged as they are received into the node at both locations, without conflicts. This works very well because different users&#x2F;instances tend to update different points. The exception to this may occur when a user at the edge and a cloud user update a config item at the same time. In this case, we simply use the point with the latest timestamp.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;The storage and communication infrastructure does not change.&lt;&#x2F;strong&gt; One of the biggest problems in traditional storage mechanisms and network APIs is that schema and encoding changes can be very painful. If you add a field to a data structure, every piece of code that touches the data as it travels throughout the system needs to be updated. With nodes and points, only the ends of your system need to be updated. Everything in between (transmission, storage, sync, etc) can stay the same.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image-4.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Introspection and monitoring are easy.&lt;&#x2F;strong&gt; Since our data format is simple and fixed, it is easy to watch and decode traffic anywhere to see what is going on.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Integration is easy.&lt;&#x2F;strong&gt; Because we have standardized the data to be very simple, it is easy for one service to provide data that another can use.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Everything is data that can be acted upon.&lt;&#x2F;strong&gt; In the past, we might have had a rules engine that could respond to sensor data changes. Since config changes are now the same kind of data, the rules engine can now respond to and make config changes as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;History is easily logged for all changes.&lt;&#x2F;strong&gt; Likewise, since config and sensor sample data are now the same type of data, everything that happens in the system can be easily recorded in history. The system is automatically auditable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;It is efficient.&lt;&#x2F;strong&gt; Because the data is granular, only what changes is transmitted and processed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;It works both internally and externally.&lt;&#x2F;strong&gt; While this data scheme was primarily developed to efficiently communicate between systems connected by networks, it also works very well for communicating between threads in an application. When an application is architected this way, it is very easy to extend, it as the communication scheme internally and externally is the same. This architecture scales.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;objections&quot;&gt;Objections&lt;&#x2F;h2&gt;
&lt;p&gt;🚩&lt;strong&gt;Objection #1: But isn’t this a lot of overhead to store a type&#x2F;key&#x2F;timestamp&#x2F;etc with every bit of data?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We need to focus on where the bottlenecks&#x2F;hard&#x2F;expensive parts of the system are. Synchronizing data from many different instances over networks is the hard part of IoT systems. Local storage and CPU processing are relatively cheap in comparison. Networks are also relatively slow compared to the additional processing time required to process this data. CPU and storage are now abundant, even on microcontrollers. Development, operations, and deployment are not cheap.&lt;&#x2F;p&gt;
&lt;p&gt;🚩 &lt;strong&gt;Objection #2: Nodes and Points are hard to deal with.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;True, dealing with raw &lt;code&gt;nodes&lt;&#x2F;code&gt; and &lt;code&gt;points&lt;&#x2F;code&gt; is not as convenient as a &lt;code&gt;struct&lt;&#x2F;code&gt;, but we &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;data&quot;&gt;can create tools&lt;&#x2F;a&gt; that easily convert &lt;code&gt;structs&lt;&#x2F;code&gt; to and from &lt;code&gt;nodes&#x2F;points&lt;&#x2F;code&gt;. We do it all the time – JSON, Protobuf, etc. Computers are very good at encoding&#x2F;decoding data – let them do it.&lt;&#x2F;p&gt;
&lt;p&gt;🚩 &lt;strong&gt;Objection #3: How do you protect your data if anyone can update anything?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;AuthZ&#x2F;AuthN is a valid concern and has not been fully solved yet. One idea is to authorize access to data at the node level – each user or instance would have access to a set of nodes. However, this says that an edge device could change its own config parameters. Perhaps this is OK because, without physical security, you don’t have true security. It may also be useful to differentiate between&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nats.io&#x2F;running-a-nats-service&#x2F;configuration&#x2F;securing_nats&#x2F;authorization#permissions-configuration-map&quot;&gt;read and write access&lt;&#x2F;a&gt; to node data. Ideas are welcome!&lt;&#x2F;p&gt;
&lt;p&gt;🚩 &lt;strong&gt;Objection #4: If points for a single struct are flowing in at different times, how do I know when a change is complete and when to process it?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is also a valid concern. One option is to set a timer that gets reset any time the config changes, and the changes are only processed once the timer expires. With a little creativity, we can probably come up with other schemes to signal the change is complete – perhaps a special point that is sent at the end of a sequence of points.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #5: What if the data is more complex than what can be represented with a simple data type like a number or string?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can store anything you want in the point data field (JSON, Protobuf, etc.) This should provide enough flexibility for things like messages, where it probably does not make sense to separate the data into separate points.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #6: How do you deal with schema changes?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There may be instances where there are point type name changes, node topography changes, etc. In this case, each client, which provides the backend code for a node type, should be responsible for handling any schema changes. This localizes the migration logic to each client (including external clients that plug into the system at runtime) rather than requiring a central system to understand all migrations. A node may contain a version point if necessary.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #7: Do I have to represent all my data as points?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If data needs to be distributed between instances on a network, then it is very beneficial to use points. However, for local processing of data, there is nothing preventing you from using more conventional techniques, storage, etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #8: How do you store data as nodes and points? SQL databases are not designed for this.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That is an excellent question and part of our research in the Simple IoT project. We are currently using SQLite, but we are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;adr&#x2F;7-jetstream-store.html&quot;&gt;moving to NATS Jetstream&lt;&#x2F;a&gt;. Stay tuned!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #9: Will this scale to a bazillion devices?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Probably not. If you need to connect a bazillion devices, then perhaps AWS IoT or something else is a better fit. However, what we are presenting here is a flexible architecture that will scale over time to many different applications and configurations as your needs evolve and change. How do you want to scale? Think carefully about this, as scaling in one dimension sometimes limits how far you can scale in another.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #10: This will not work for data sampled at 100 bazillion samples per second.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For moderate data rates, transmitting blocks of data with every point by putting an array of data in a point data field may work. For high-rate data that flows, a custom data encoding and transport will likely be required.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #11: You can’t depend on time in a computer system, so last-write-wins (LWW) is not reliable.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;True, time, like networks, is not always reliable. However, in IoT systems, most of the time, you do not have the same data being edited in multiple locations, so LWW is only used in the rare case where two human users make changes at different locations. A little clock drift is not a huge deal. You can also do things like check if two systems have similar times before you synchronize data between them, and verify a system has a valid time before writing any data. You can also require that every instance in the system has its own RTC clock and that some engineering effort is made to ensure it is reliable and reasonably accurate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #12: Why not send commands, events, changes, etc.?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sending “commands” is a common paradigm in IoT systems, but it is the siren song into complexity. How do you deal with cases where the command does not make it due to a network problem? There are valid cases for events such as orders or notifications, but in most cases, commands&#x2F;events are an unnecessary abstraction and only complicate things. A sensor is at value X. The config setting is Y. Keep things declarative. Just send the data itself, keep some amount of history, and if you want to know when something changed, look at history. Utilizing new technologies like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;adr&#x2F;7-jetstream-store.html&quot;&gt;NATs Jetstream&lt;&#x2F;a&gt; is a critical piece of this puzzle.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #13: But this is different !?!?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yup, I’ve never seen anything like it before either. But it works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;When we want to advance something, we often need to simplify it first.&lt;&#x2F;strong&gt; Piling on layers of complexity will only get us so far – at times, we need to go back to ground zero and re-think things.&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways to specify contracts between systems, such as APIs and schemas. A more fundamental contract focuses on a more granular unit of data. Points in an IoT system are like atoms in matter. A Node tree in an IoT system is like the DNA in a living organism. The composition of points and structure of nodes (like atoms and DNA) is infinitely flexible. It is this simplicity and flexibility that allows atoms and DNA to define so many different types of matter and species of organisms. It is time to throw out the custom struct as the defined unit of data between systems and focus on something more granular, flexible, and scalable.&lt;&#x2F;p&gt;
&lt;p&gt;Want to learn more? Check out and follow the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;&quot;&gt;Simple IoT project&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 The secret to process</title>
        <published>2025-03-28T00:00:00+00:00</published>
        <updated>2025-03-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0140-the-secret-to-process/"/>
        <id>https://bec-systems.com/blog/0140-the-secret-to-process/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0140-the-secret-to-process/">&lt;p&gt;Process&#x2F;workflows&#x2F;tools should be good enough that they help the people doing
the work. They are not just an administrative tool. Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Git helps me manage my own work, so I use it even on personal projects where
collaboration is not needed.&lt;&#x2F;li&gt;
&lt;li&gt;Gitea issues are so fast and easy to use that when working on hard problems, I
automatically create an issue to log progress. It is easier and faster than
keeping notes anywhere else.&lt;&#x2F;li&gt;
&lt;li&gt;Gitea releases are so quick and easy to use that I use them even for internal
releases there rather than composing an email.&lt;&#x2F;li&gt;
&lt;li&gt;Jitsi Meet is easier than a phone call, so we use it for most calls and have
the benefit of screen sharing, video, multiple participants, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Code formatting tools help me as a developer, so I gladly integrate them into
my editor.&lt;&#x2F;li&gt;
&lt;li&gt;Part numbers are so easy to pull and use that they help me manage parts and
assemblies for my prototype builds, so I pull them early in the design process
and integrate them in CAD libraries.&lt;&#x2F;li&gt;
&lt;li&gt;Tests are easy to create and run locally, so I create them as part of my
development process.&lt;&#x2F;li&gt;
&lt;li&gt;Documentation is integrated with the design files and easy to create, edit,
and track. Thus, documentation is an integral part of the development process
vs. an afterthought.&lt;&#x2F;li&gt;
&lt;li&gt;End to end tests are easy to run by anyone, so when there are issues to debug,
they are tool that is regularly used by developers.&lt;&#x2F;li&gt;
&lt;li&gt;It is easy to purchase things needed to do my job and improve the company as
everyone is issued a credit card, and expense reports are generated
automatically. There is no motivation to bypass the process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Tools&#x2F;workflows&#x2F;process should help the people doing the work go faster, not
slow them down. If this is the case, you won’t need to force them on people. If
this is not the case, the process needs work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚙️ Fix systems, not people</title>
        <published>2025-03-27T00:00:00+00:00</published>
        <updated>2025-03-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0139-fix-systems-not-people/"/>
        <id>https://bec-systems.com/blog/0139-fix-systems-not-people/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0139-fix-systems-not-people/">&lt;p&gt;We can rarely “fix” other people. Short of a divine conversion experience or a
life-changing event, people don’t fundamentally change, no matter how much we
plead, beg, threaten, cajole, encourage, etc. Certainly, some are more gifted
with the ability to motivate, nurture, and mentor others. But, even this has
limits. So we are left with two options:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;first-who-then-what.html&quot;&gt;Get the right people on the bus.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Work on the systems and processes that help all of us work and communicate
more effectively.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 Scaling</title>
        <published>2025-03-26T00:00:00+00:00</published>
        <updated>2025-03-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0138-scaling/"/>
        <id>https://bec-systems.com/blog/0138-scaling/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0138-scaling/">&lt;p&gt;We often think of scaling as growing a company’s size or the number of units
sold&#x2F;deployed&#x2F;etc. That is one way to provide value to the world.&lt;&#x2F;p&gt;
&lt;p&gt;However, there are other ways to scale:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;improving the experience&lt;&#x2F;li&gt;
&lt;li&gt;improving reliability&#x2F;security&lt;&#x2F;li&gt;
&lt;li&gt;new markets&lt;&#x2F;li&gt;
&lt;li&gt;deploying updates to existing systems&lt;&#x2F;li&gt;
&lt;li&gt;better customer support&lt;&#x2F;li&gt;
&lt;li&gt;giving users more control&#x2F;flexibility&#x2F;customization&lt;&#x2F;li&gt;
&lt;li&gt;higher profit margins&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Think carefully about this as scaling in one dimension often limits how far you
can scale in another.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌅 Simple stuff is boring</title>
        <published>2025-03-25T00:00:00+00:00</published>
        <updated>2025-03-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0137-simple-stuff-is-boring/"/>
        <id>https://bec-systems.com/blog/0137-simple-stuff-is-boring/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0137-simple-stuff-is-boring/">&lt;p&gt;That may be. But doing the simple stuff well is also rewarding. And which is
better: exciting or rewarding?&lt;&#x2F;p&gt;
&lt;p&gt;To do the simple stuff well feels good. It feels right. That is because it is
right. And what gets the simple stuff done? YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👌 The simple&#x2F;basic things are the most important to get right</title>
        <published>2025-03-24T00:00:00+00:00</published>
        <updated>2025-03-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0136-wqthe-simple-basic-things-are-the-most-important-to-get-right/"/>
        <id>https://bec-systems.com/blog/0136-wqthe-simple-basic-things-are-the-most-important-to-get-right/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0136-wqthe-simple-basic-things-are-the-most-important-to-get-right/">&lt;p&gt;It pretty much any endeavor, consistently doing the simple things are what make
the difference.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Doing simple exercises consistently.&lt;&#x2F;li&gt;
&lt;li&gt;Eating whole foods.&lt;&#x2F;li&gt;
&lt;li&gt;Not overeating.&lt;&#x2F;li&gt;
&lt;li&gt;Taking time to share and communicate.&lt;&#x2F;li&gt;
&lt;li&gt;Showing up.&lt;&#x2F;li&gt;
&lt;li&gt;Being on time.&lt;&#x2F;li&gt;
&lt;li&gt;Meeting commitments.&lt;&#x2F;li&gt;
&lt;li&gt;Not overcomitting.&lt;&#x2F;li&gt;
&lt;li&gt;Using a headset when communicating.&lt;&#x2F;li&gt;
&lt;li&gt;Fixing bugs.&lt;&#x2F;li&gt;
&lt;li&gt;Keeping code clean.&lt;&#x2F;li&gt;
&lt;li&gt;Following the process.&lt;&#x2F;li&gt;
&lt;li&gt;Having a process.&lt;&#x2F;li&gt;
&lt;li&gt;Working transparently.&lt;&#x2F;li&gt;
&lt;li&gt;Making things easier for others.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Simple things are foundational – if you don’t get these right, the rest
crumbles.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✅ The problem with software</title>
        <published>2025-03-21T00:00:00+00:00</published>
        <updated>2025-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0135-the-problem-with-software/"/>
        <id>https://bec-systems.com/blog/0135-the-problem-with-software/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0135-the-problem-with-software/">&lt;p&gt;I’m currently reading
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;atulgawande.com&#x2F;book&#x2F;the-checklist-manifesto&#x2F;&quot;&gt;The Checklist Manifesto &lt;&#x2F;a&gt;
by Atul Gawande. Gawande is a surgeon who wants to find a way to reduce the
mistakes and their catastrophic consequences during surgery. So he investigates
other industries such as air travel and the construction of large buildings.
What he finds is the checklist is at the center of their processes. (more on
this later …)&lt;&#x2F;p&gt;
&lt;p&gt;With software, our failures (with some exceptions) are usually not as
catastrophic as people dying in surgery, airplanes falling out of the sky, and
large buildings collapsing. Another difference with software is that is easy and
cheap to fix by deploying an update (hence the prefix “soft”). People,
airplanes, and buildings are not this way.&lt;&#x2F;p&gt;
&lt;p&gt;Thus we can get sloppy. Motivation to “get it right” can wane as pressure to
ship increases and we can “always fix it later.” The problem is that this
approach encourages accumulating technical debt. Technical debt will just as
surely crush the soul of a programmer and eventually the company, just not in
dramatic news-catching ways.&lt;&#x2F;p&gt;
&lt;p&gt;Building a sustainable technology company requires an extreme level of
discipline because there is no external force requiring you to do it right. For
many technology industries, there is not any regulatory agency watching over
them – it is entirely up to YOU, and that is where YOUR Platform comes in.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌻 Downstream, things should be better</title>
        <published>2025-03-20T00:00:00+00:00</published>
        <updated>2025-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0134-downstream-things-should-be-better/"/>
        <id>https://bec-systems.com/blog/0134-downstream-things-should-be-better/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0134-downstream-things-should-be-better/">&lt;p&gt;For everyone downstream of us who uses or is influenced by what we create or do,
things should be simpler&#x2F;better&#x2F;easier – because we did something. This is the
formula for creating wealth.&lt;&#x2F;p&gt;
&lt;p&gt;The alternative is that we produce no value for others. It would be easier for
someone to do whatever we’re doing themselves, or in extreme cases what we are
doing should not be done at all. This is the formula for debt.&lt;&#x2F;p&gt;
&lt;p&gt;Wealth can include more than money – good will, positive energy, intellectual
property, spiritual well-being, relationships, community, health, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Whenever debt creation is greater than wealth creation for too long, the
family&#x2F;organization&#x2F;company&#x2F;country we’re a part of collapses.&lt;&#x2F;p&gt;
&lt;p&gt;In whatever sphere we’re a part of, do we create wealth or debt.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🪙 Complexity and Simplicity -- two sides of the same coin</title>
        <published>2025-03-19T00:00:00+00:00</published>
        <updated>2025-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0133-complexity-and-simplicity-two-sides-of-the-same-coin/"/>
        <id>https://bec-systems.com/blog/0133-complexity-and-simplicity-two-sides-of-the-same-coin/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0133-complexity-and-simplicity-two-sides-of-the-same-coin/">&lt;p&gt;To get to simple for someone, it often has to get more complex for someone else.&lt;&#x2F;p&gt;
&lt;p&gt;An elegant, easy to use UI was a lot of work for someone to design.&lt;&#x2F;p&gt;
&lt;p&gt;A powerful, modern programming language that makes it easy for software
developers was no doubt very complex to implement.&lt;&#x2F;p&gt;
&lt;p&gt;Modern CPUs that allow us to do so much are very complex to design and
manufacture.&lt;&#x2F;p&gt;
&lt;p&gt;In technology, anything that appears simple&#x2F;nice&#x2F;easy likely has something very
complex behind the scenes.&lt;&#x2F;p&gt;
&lt;p&gt;Again, this makes business sense if many people can benefit from the simplicity
for every person that deals with the complexity.&lt;&#x2F;p&gt;
&lt;p&gt;What does not work is if we push complexity onto our users&#x2F;customers in an
effort to keep things simple for ourselves.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⬆️ The business case for improvement</title>
        <published>2025-03-18T00:00:00+00:00</published>
        <updated>2025-03-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0132-the-business-case-for-improvement/"/>
        <id>https://bec-systems.com/blog/0132-the-business-case-for-improvement/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0132-the-business-case-for-improvement/">&lt;p&gt;As discussed previously, improvement is sometimes hard – really hard. So how do
we justify it?&lt;&#x2F;p&gt;
&lt;p&gt;The payback comes when we improve something once, and then something else gets
lots easier many times.&lt;&#x2F;p&gt;
&lt;p&gt;An example might be automating a release process. If it takes 1 hour to manually
do a release, and it takes 6 hours to automate it, then in 6 releases we break
even and releases after that is gain.&lt;&#x2F;p&gt;
&lt;p&gt;We want the balance to tip heavily toward the gains from repeatedly using the
improvement, not the effort spent implementing improvements.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;a&#x2F;aea3b179c43e38f66bc9860a3d4c9e253e74c84a.png&quot; alt=&quot;balance&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For this to work out, we need a way to leverage improvements in the future. We
need tools, workflows, automation, and processes to capture improvements – YOUR
Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⬆️ The path of improvement</title>
        <published>2025-03-17T00:00:00+00:00</published>
        <updated>2025-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0131-the-path-of-improvement/"/>
        <id>https://bec-systems.com/blog/0131-the-path-of-improvement/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0131-the-path-of-improvement/">&lt;p&gt;Improvement is not always easy, actually it is usually hard – really hard, and
sometimes a complex path. But in the end, something likely
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0130-what-is-improvement&#x2F;&quot;&gt;got simpler for someone&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Getting to complex is easy and the natural state of things (chaos).&lt;&#x2F;p&gt;
&lt;p&gt;The path and the resulting state are two different things.&lt;&#x2F;p&gt;
&lt;p&gt;We can do the hard&#x2F;complex things and get to a simple&#x2F;nice&#x2F;sustainable state.&lt;&#x2F;p&gt;
&lt;p&gt;Or we can only do the the easy things which results in a
complex&#x2F;messy&#x2F;unsustainable state.&lt;&#x2F;p&gt;
&lt;p&gt;Take your pick.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;c&#x2F;cbce40d3004bbed62fe1959b9c86ebc7d037df8f.png&quot; alt=&quot;path vs state&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⬆️ What is improvement?</title>
        <published>2025-03-14T00:00:00+00:00</published>
        <updated>2025-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0130-what-is-improvement/"/>
        <id>https://bec-systems.com/blog/0130-what-is-improvement/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0130-what-is-improvement/">&lt;p&gt;Improvement often means something got simpler for someone:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We refactored the code and it is now easier to read.&lt;&#x2F;li&gt;
&lt;li&gt;The build system is more reliable.&lt;&#x2F;li&gt;
&lt;li&gt;The automated tests are better, so less manual testing is needed.&lt;&#x2F;li&gt;
&lt;li&gt;The documentation is better, so it is easier to understand something.&lt;&#x2F;li&gt;
&lt;li&gt;The circuit is more reliable, so support has less field problems to deal with.&lt;&#x2F;li&gt;
&lt;li&gt;A product has more needed features, so it is easier to sell.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If things are not getting simpler for someone, we need to question – are they
improving?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👷 Make less work for others, part 2</title>
        <published>2025-03-13T00:00:00+00:00</published>
        <updated>2025-03-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0129-make-less-work-for-others-part-2/"/>
        <id>https://bec-systems.com/blog/0129-make-less-work-for-others-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0129-make-less-work-for-others-part-2/">&lt;p&gt;A few examples of how to make “less work” for others:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;try not to introduce bugs or break stuff&lt;&#x2F;li&gt;
&lt;li&gt;communicate in workflows like Tickets&#x2F;PRs where there is context and messages
can be easily processed&lt;&#x2F;li&gt;
&lt;li&gt;document your work – including “why”&lt;&#x2F;li&gt;
&lt;li&gt;focus on the business priorities&lt;&#x2F;li&gt;
&lt;li&gt;be self-directed – see what needs done and do it&lt;&#x2F;li&gt;
&lt;li&gt;work in public
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0101-the-importance-of-small-git-commits-pull-requests&#x2F;&quot;&gt;commit early and often&lt;&#x2F;a&gt;
and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0099-the-importance-of-git-commit-push-often&#x2F;&quot;&gt;release your work often&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;document how work was tested&lt;&#x2F;li&gt;
&lt;li&gt;better yet, provide examples&#x2F;scripts&#x2F;tests of how to use&#x2F;test your work&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It should be obvious:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;what we are doing&lt;&#x2F;li&gt;
&lt;li&gt;why we are doing it&lt;&#x2F;li&gt;
&lt;li&gt;how we did it&lt;&#x2F;li&gt;
&lt;li&gt;how we tested&#x2F;verified it&lt;&#x2F;li&gt;
&lt;li&gt;and how to use it&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👷 Do we make more work for others or less?</title>
        <published>2025-03-12T00:00:00+00:00</published>
        <updated>2025-03-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0128-do-we-make-more-work-for-others-or-less/"/>
        <id>https://bec-systems.com/blog/0128-do-we-make-more-work-for-others-or-less/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0128-do-we-make-more-work-for-others-or-less/">&lt;p&gt;This question really gets to the heart of our value to others. In everything we
do, we need to think – am I delivering this work or information in a way that
is easy for others to understand and use? Or do they need to do a bunch of
unneeded&#x2F;extra work?&lt;&#x2F;p&gt;
&lt;p&gt;Organizations composed of people who make less work for others scale.&lt;&#x2F;p&gt;
&lt;p&gt;Organizations composed of people who make more work for others collapse.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 The business model for updates</title>
        <published>2025-03-11T00:00:00+00:00</published>
        <updated>2025-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0127-the-business-model-for-updates/"/>
        <id>https://bec-systems.com/blog/0127-the-business-model-for-updates/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0127-the-business-model-for-updates/">&lt;p&gt;In the old’n days, a project was shipped and done, and we moved on to the next
one.&lt;&#x2F;p&gt;
&lt;p&gt;However, with modern connected systems, we can
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0123-connected-systems-are-different&#x2F;&quot;&gt;deliver a lot of value&lt;&#x2F;a&gt;
after the initial release. Most of our engineering effort may be spent after the
initial release maintaining and improving a product. How do we fund this? Some
ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Build the cost into the product up front (many consumer products use this
model)&lt;&#x2F;li&gt;
&lt;li&gt;Pay for maintenance with new sales (be careful this is not a pyramid scheme)&lt;&#x2F;li&gt;
&lt;li&gt;Monthly&#x2F;yearly subscription fees (might include a cloud service)&lt;&#x2F;li&gt;
&lt;li&gt;Fees for add-on features (high-end test equipment like oscilloscopes often use
this model)&lt;&#x2F;li&gt;
&lt;li&gt;Pay for every update (hard to get customer buy-in)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The biggest mistake is not to plan for maintenance costs, or to surprise your
customers with them. Be up front with the costs, but be more up front by
communicating the value that you are continuously delivering.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 What is the best software release frequency?</title>
        <published>2025-03-10T00:00:00+00:00</published>
        <updated>2025-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0126-what-is-the-best-software-release-frequency/"/>
        <id>https://bec-systems.com/blog/0126-what-is-the-best-software-release-frequency/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0126-what-is-the-best-software-release-frequency/">&lt;p&gt;Different projects&#x2F;products have different needs, but generally the trend in our
industry is to release new software more often. There are several reasons for
this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Modern processors (even embedded microcontrollers) are very powerful and
expandable, so it is possible to add additional features after the initial
release.&lt;&#x2F;li&gt;
&lt;li&gt;Many devices are now connected, so updates can be deployed “over the air”
automatically, rather than executing some manual operation.&lt;&#x2F;li&gt;
&lt;li&gt;Continuous Integration (CI) and other workflows are improving the quality of
software such that we are more confident the software is always tested and
working. Long manual testing&#x2F;QA periods are no longer the best practice.&lt;&#x2F;li&gt;
&lt;li&gt;People are used to software updating on their phones&#x2F;computers, so it is
generally more accepted.&lt;&#x2F;li&gt;
&lt;li&gt;Connected systems
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0123-connected-systems-are-different&#x2F;&quot;&gt;need more updates&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Connected systems bring security concerns which require updates.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Perhaps the main reason the release frequency is increasing is more cultural
than anything. In previous times, software updates were perceived as “breaking
things.” Especially in embedded systems, the mantra was: test it extensively,
get it right, and lock things down. Updates are risky. However, the world has
changed.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, a software release means more value is being delivered to your
users. And if our goal is to deliver value, then that includes releasing new
software more often.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 How can Arch Linux get by without releases?</title>
        <published>2025-03-07T00:00:00+00:00</published>
        <updated>2025-03-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0125-how-can-arch-linux-get-by-without-releases/"/>
        <id>https://bec-systems.com/blog/0125-how-can-arch-linux-get-by-without-releases/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0125-how-can-arch-linux-get-by-without-releases/">&lt;p&gt;Arch Linux does not have discrete releases – it is a rolling distribution where
individual packages are continuously updated. Most people still raise an eyebrow
at the mention of Arch Linux – how can that possibly work and be stable?&lt;&#x2F;p&gt;
&lt;p&gt;Having run Arch for many years, I can affirm
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;022&#x2F;&quot;&gt;it works very well&lt;&#x2F;a&gt;. It is fast, efficient, and lets
me run the latest software of everything with minimal fuss.&lt;&#x2F;p&gt;
&lt;p&gt;Today, a Linux distribution release is an artificial notion. A distribution’s
main job is to deliver a collection of software to a computer. Each application
has its own release cadence. Imposing a distribution release cadence on top of
the package release cycle does not make sense.&lt;&#x2F;p&gt;
&lt;p&gt;But the distribution’s job is ensuring everything is stable and works together?
Really? Does a distribution really test every one of the 1000’s of packages
before every release?&lt;&#x2F;p&gt;
&lt;p&gt;If there is a serious problem in an application, it will be fixed soon in the
main development branch. Requiring these fixes to be back-ported to an old
release in a distribution is a lot of work. In some cases, it is nearly
impossible to backport a change if things have changed significantly in the
codebase.&lt;&#x2F;p&gt;
&lt;p&gt;A Linux distribution delivers the most value when each software package can be
deployed to its users as soon as it is ready. Arch does this and then gets out
of the way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Truth is discovered, not invented</title>
        <published>2025-03-06T00:00:00+00:00</published>
        <updated>2025-03-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0124-truth-is-discovered-not-invented/"/>
        <id>https://bec-systems.com/blog/0124-truth-is-discovered-not-invented/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0124-truth-is-discovered-not-invented/">&lt;p&gt;I once advised a young man – If you have some down time on a plane, in a hotel,
etc., you might consider writing an essay or two about some of the issues facing
you personally, or your organization. This is one of the best ways to think and
discover truths. I’m often surprised and amazed what comes out.&lt;&#x2F;p&gt;
&lt;p&gt;Meetings would be much more effective if writing were part of the preparation
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;telcoldtakes.substack.com&#x2F;p&#x2F;a-case-for-the-amazon-6-pager&quot;&gt;Amazon does this&lt;&#x2F;a&gt;).
But, alas, most think we can make progress by more discussion, meetings, emails,
etc.&lt;&#x2F;p&gt;
&lt;p&gt;Truth is discovered, not invented. Truth cannot be forced. It is only when we
approach the creative process with this humility that we can make progress.
Designs devoid of truth are unwieldy, unreliable, hard to maintain, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Modern, powerful tools like AI, CAD, computer languages, etc, may give us the
illusion that great inventions start with us, but truly great
designs&#x2F;algorithms&#x2F;processes are discovered, a simple reflection of truths that
have existed for eternity. In the process of simplifying our designs, we often
come closer to truth.&lt;&#x2F;p&gt;
&lt;p&gt;I wish I had understood the power of writing and the essence of truth earlier in
my career.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔗 Connected systems are different</title>
        <published>2025-03-05T00:00:00+00:00</published>
        <updated>2025-03-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0123-connected-systems-are-different/"/>
        <id>https://bec-systems.com/blog/0123-connected-systems-are-different/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0123-connected-systems-are-different/">&lt;p&gt;In distributed computer systems, change is the constant.&lt;&#x2F;p&gt;
&lt;p&gt;Because a system can be networked, its capabilities are endless. The ability to
connect to new and different systems means new systems (and value) can always be
created, and &lt;strong&gt;&lt;em&gt;things will change&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you don’t, somebody else will.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛡️ How to get to secure and reliable</title>
        <published>2025-03-04T00:00:00+00:00</published>
        <updated>2025-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0122-how-to-get-to-secure-and-reliable/"/>
        <id>https://bec-systems.com/blog/0122-how-to-get-to-secure-and-reliable/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0122-how-to-get-to-secure-and-reliable/">&lt;p&gt;The best way to get to secure and reliable software is to fix the core issues.&lt;&#x2F;p&gt;
&lt;p&gt;If your programming language is not reasonably secure and reliable, adding more
external tools to check and track down problems is helpful, but is likely not
the most direct approach.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise with architecture – getting the core architecture right is important.
Adding external “watchers” and “fixers” to compensate for an architectural
problem only complicates things, and complexity is the #1 enemy to both security
and reliability.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏭 Semi-structured part numbers</title>
        <published>2025-02-28T00:00:00+00:00</published>
        <updated>2025-02-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0121-semi-structured-part-numbers/"/>
        <id>https://bec-systems.com/blog/0121-semi-structured-part-numbers/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0121-semi-structured-part-numbers/">&lt;p&gt;Some time back I recorded a video on Semi-structured part numbers.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;youtu.be&#x2F;tlsl01uxUfE&lt;&#x2F;p&gt;
&lt;p&gt;Be more efficient.&lt;&#x2F;p&gt;
&lt;p&gt;Make less mistakes.&lt;&#x2F;p&gt;
&lt;p&gt;We tend to ignore simple things like part numbering systems.&lt;&#x2F;p&gt;
&lt;p&gt;But doing the simple things right is what frees us up to work on the hard
things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👤 Who is our &quot;customer&quot;?</title>
        <published>2025-02-27T00:00:00+00:00</published>
        <updated>2025-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0120-who-is-our-customer/"/>
        <id>https://bec-systems.com/blog/0120-who-is-our-customer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0120-who-is-our-customer/">&lt;p&gt;Your “customer” is someone who derives value and uses what you produce.
Customers are both internal and external to your organization.&lt;&#x2F;p&gt;
&lt;p&gt;While it is good to focus on the flow of primary business value to the
end-customer (that is what pays the bills), we can also think of everyone in the
organization as being our customer. How can we provide value to everyone?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚠️ Toward a Theory of Medical Fallibility</title>
        <published>2025-02-26T00:00:00+00:00</published>
        <updated>2025-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0119-toward-a-theory-of-medical-fallibility/"/>
        <id>https://bec-systems.com/blog/0119-toward-a-theory-of-medical-fallibility/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0119-toward-a-theory-of-medical-fallibility/">&lt;p&gt;I recently skimmed an essay from 1975 titled
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jstor.org&#x2F;stable&#x2F;3560992&quot;&gt;Toward a Theory of Medical Fallibility&lt;&#x2F;a&gt;.
A few quotes from the article:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Therefore, where there is scientific activity, there is a partial ignorance
– the ignorance that exists as a precondition for scientific progress. And
since ignorance is a precondition of progress, where there is the
possibility of progress there is the possibility of error. This ignorance of
what is not yet known is the permanent state of all science and a source of
error even when all the internal norms of science have been fully respected.&lt;&#x2F;li&gt;
&lt;li&gt;Error may indeed arise from the present state of scientific ignorance or
from willfulness or negligence. But it may also arise precisely from this
third factor which we have called necessary fallibility in respect to
particulars.&lt;&#x2F;li&gt;
&lt;li&gt;The encouragement of this inflated belief in the competence of the physician
is of course reinforced by the practice of not keeping systematic and
accessible records of medical error. Yet everyone knows that this is a false
confidence.&lt;&#x2F;li&gt;
&lt;li&gt;Indeed, the only profession of which we know which fully and publicly
documents predictive successes and failures is that of horse-racing
correspondents in Great Britain.&lt;&#x2F;li&gt;
&lt;li&gt;The first reaction of physicians to the invitation to dispense with the
masks of infallibility is likely to be a humane alarm at the insecurity
which a frank acceptance of medical fallibility might engender in the
patient. But we wonder whether the present situation, in which the
expectations of patients are so very often disappointed during medical
treatment, is not a worse source of insecurity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;As computer&#x2F;software systems get more complex, are there parallels?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛤️ Two paths with experience</title>
        <published>2025-02-24T00:00:00+00:00</published>
        <updated>2025-02-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0118-two-paths-with-experience/"/>
        <id>https://bec-systems.com/blog/0118-two-paths-with-experience/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0118-two-paths-with-experience/">&lt;p&gt;As we gain experience, we can take two paths:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;learn from mistakes and all the things that went wrong, and apply this
knowledge to do better in the future.&lt;&#x2F;li&gt;
&lt;li&gt;assume because we’ve done something before the next time we do something
similar it will “just work.”&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If I’ve learned anything working in technology, things rarely “just work.”
Nothing is easy.&lt;&#x2F;p&gt;
&lt;p&gt;Some can accomplish #1 because they have a great memory. For the rest of us, we
need some process to capture what we have learned and a mechanism for applying
this in the future.&lt;&#x2F;p&gt;
&lt;p&gt;A checklist is a great place to start.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛤️ Two paths</title>
        <published>2025-02-21T00:00:00+00:00</published>
        <updated>2025-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0117-two-paths/"/>
        <id>https://bec-systems.com/blog/0117-two-paths/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0117-two-paths/">&lt;p&gt;There are two paths we can follow as a team or an organization:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;what we do makes it &lt;strong&gt;easier&lt;&#x2F;strong&gt; for everyone else to do their job.&lt;&#x2F;li&gt;
&lt;li&gt;what we do makes it &lt;strong&gt;harder&lt;&#x2F;strong&gt; for everyone else to do their job.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;#1 is the formula for &lt;strong&gt;scaling&lt;&#x2F;strong&gt;. #2 is the formula for stagnation and
&lt;strong&gt;technical debt&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;And which path a team or organization takes depends on &lt;strong&gt;culture&lt;&#x2F;strong&gt;. What are the
&lt;strong&gt;expectations&lt;&#x2F;strong&gt;? Are they &lt;strong&gt;documented&lt;&#x2F;strong&gt;? And most importantly, what
&lt;strong&gt;example&lt;&#x2F;strong&gt; do we set?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Your team as the customer</title>
        <published>2025-02-20T00:00:00+00:00</published>
        <updated>2025-02-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0116-your-team-as-the-customer/"/>
        <id>https://bec-systems.com/blog/0116-your-team-as-the-customer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0116-your-team-as-the-customer/">&lt;p&gt;Previously we
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0113-who-is-the-customer-in-organizational-hierarchy&#x2F;&quot;&gt;defined our “customer”&lt;&#x2F;a&gt;
as someone who derives value from what we do. While it is useful to think of how
the primary business value is flowing, hopefully we are providing value to our
team as well as people outside our team. Some ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Are Git commit messages helpful and easy to understand?&lt;&#x2F;li&gt;
&lt;li&gt;Are commits and PRs small enough to comprehend?&lt;&#x2F;li&gt;
&lt;li&gt;Is our work transparent?&lt;&#x2F;li&gt;
&lt;li&gt;Do we deliver what we said we would?&lt;&#x2F;li&gt;
&lt;li&gt;Is the code we write easy to follow and maintain?&lt;&#x2F;li&gt;
&lt;li&gt;Do we document what we are doing and why?&lt;&#x2F;li&gt;
&lt;li&gt;Do we share tests scripts and other automation that helps people use what we
created?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Why are releases important?</title>
        <published>2025-02-19T00:00:00+00:00</published>
        <updated>2025-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0115-why-are-releases-important/"/>
        <id>https://bec-systems.com/blog/0115-why-are-releases-important/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0115-why-are-releases-important/">&lt;p&gt;Since many products&#x2F;systems run software these days, they can be improved after
the initial release. Most software projects have “releases” when a new version
of the software is deployed or made available.&lt;&#x2F;p&gt;
&lt;p&gt;Why are releases so important? Some reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Communicates to customers an update is available and what changed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Provides a cadence for doing work.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Encourages development teams to “ship”. Shipping is motivating.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Delivers more value to the customer.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Helps us isolate problems if we know what is running and what changed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📄 Who is a changelog for?</title>
        <published>2025-02-18T00:00:00+00:00</published>
        <updated>2025-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0114-who-is-a-changelog-for/"/>
        <id>https://bec-systems.com/blog/0114-who-is-a-changelog-for/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0114-who-is-a-changelog-for/">&lt;p&gt;Most projects have releases, and with each release, we describe what is
new&#x2F;changed&#x2F;fixed in a changelog file.
&lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0114-who-is-a-changelog-for&#x2F;%5Bhttps:&#x2F;&#x2F;keepachangelog.com%5D(https:&#x2F;&#x2F;keepachangelog.com&#x2F;)&quot;&gt;keep a changelog&lt;&#x2F;a&gt;
has a lot of good ideas.&lt;&#x2F;p&gt;
&lt;p&gt;Who is a changelog for? It is for our customers – those who use whatever we
produce. The changelog communicates to our customers what is new and valuable
&lt;strong&gt;&lt;em&gt;for them&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; in each release.&lt;&#x2F;p&gt;
&lt;p&gt;Once we realize who the changelog is for, then this can influence how we write
changelog entries. A few ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;keep it is as succinct as possible (don’t waste people’s time)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;don’t use technical jargon that our customers don’t understand&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;be humble – if there are bugs that got fixed, acknowledge they were bugs.
Don’t try to embellish or gloss over bug fixes by calling them features, etc.
People can see right through this.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;explain changes from the lens of benefits to the customer&#x2F;user, not from the
developer’s perspective&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Who is the customer in organizational hierarchy?</title>
        <published>2025-02-17T00:00:00+00:00</published>
        <updated>2025-02-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0113-who-is-the-customer-in-organizational-hierarchy/"/>
        <id>https://bec-systems.com/blog/0113-who-is-the-customer-in-organizational-hierarchy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0113-who-is-the-customer-in-organizational-hierarchy/">&lt;p&gt;In a business organization hierarchy, where E (engineer) reports to M (manager),
who is the customer in the E - M relationship?&lt;&#x2F;p&gt;
&lt;p&gt;Our first inclination may be to think M is the customer – M is the boss, E
should make M happy. But, lets think about this a bit more. Who does E create
business value for? Is E writing code that benefits M, or producing a printed
circuit board that M will directly use?&lt;&#x2F;p&gt;
&lt;p&gt;Hmm, does not seem so. E’s customer is probably purchasing and manufacturing (in
the case of a PCB). M does not directly produce tangible outputs. M’s job is to
help E get the job done. Therefore, it would follow that E is M’s customer.
Certainly, M has authority and needs to make decisions at times. But, in the
end, the job must get done. Business value must be produced. In product
development, authority or decision-making in themselves do not produce business
value. The more people we have under us, the more people we serve.&lt;&#x2F;p&gt;
&lt;p&gt;Do we exist to serve, or be served? The higher up we go, the more important it
is to understand &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;035&#x2F;&quot;&gt;servant-leadership&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👤 Confusion about when we are the customer</title>
        <published>2025-02-06T00:00:00+00:00</published>
        <updated>2025-02-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0112-confusion-about-when-we-are-the-customer/"/>
        <id>https://bec-systems.com/blog/0112-confusion-about-when-we-are-the-customer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0112-confusion-about-when-we-are-the-customer/">&lt;p&gt;In our modern, entitled, self-serving consumer culture, we tend to be confused
about when we are the customer or not. If we work for pay, our job is to do
something to benefit someone else – our customer. We are not the customer in
this scenario, someone else is. We are supposed to make someone else’s life
easier or better. In our job role, are we serving our customer, or do we expect
to be served? This mindset probably does more than anything to determine if we
are useful.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🕊️ Simple -- from whose perspective?</title>
        <published>2025-02-05T00:00:00+00:00</published>
        <updated>2025-02-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0111-simple-from-whose-perspective/"/>
        <id>https://bec-systems.com/blog/0111-simple-from-whose-perspective/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0111-simple-from-whose-perspective/">&lt;p&gt;“Just keep it simple” – we sometimes hear this. But from whose perspective?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Legal&#x2F;IP&lt;&#x2F;li&gt;
&lt;li&gt;Management&lt;&#x2F;li&gt;
&lt;li&gt;IT&lt;&#x2F;li&gt;
&lt;li&gt;Financial&lt;&#x2F;li&gt;
&lt;li&gt;R&amp;amp;D&lt;&#x2F;li&gt;
&lt;li&gt;Security&lt;&#x2F;li&gt;
&lt;li&gt;Sustaining engineering&lt;&#x2F;li&gt;
&lt;li&gt;Purchasing&lt;&#x2F;li&gt;
&lt;li&gt;Manufacturing&lt;&#x2F;li&gt;
&lt;li&gt;Quality&lt;&#x2F;li&gt;
&lt;li&gt;Sales&#x2F;Marketing&lt;&#x2F;li&gt;
&lt;li&gt;Customer support&lt;&#x2F;li&gt;
&lt;li&gt;End User&#x2F;Customer&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;How do we prioritize simplicity for the above list?&lt;&#x2F;p&gt;
&lt;p&gt;Hint, the one at the bottom is probably the most important. Do you constantly
keep your customers in mind as you make decisions? “Customer” may include
multiple from the above list.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🕊️ Simple to maintain vs simple to implement</title>
        <published>2025-02-04T00:00:00+00:00</published>
        <updated>2025-02-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0110-simple-to-maintain-vs-simple-to-implement/"/>
        <id>https://bec-systems.com/blog/0110-simple-to-maintain-vs-simple-to-implement/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0110-simple-to-maintain-vs-simple-to-implement/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0108-simple-to-use-vs-simple-to-implement&#x2F;&quot;&gt;Recently&lt;&#x2F;a&gt;
we talked about the tension between simple to use vs. simple to implement.&lt;&#x2F;p&gt;
&lt;p&gt;Maintenance is similar. If you want something that is easy to maintain, you need
to put in the work upfront.&lt;&#x2F;p&gt;
&lt;p&gt;The Elm programming is a classic example of this. The initial coding takes
longer than generating some Javascript from AI prompt. You need to figure out
how to best represent the problem with Types. But after you get it right, it is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;do-you-want-easier-to-maintain-frontend-code&#x2F;1258&quot;&gt;so easy to maintain&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 Integrate early</title>
        <published>2025-02-03T00:00:00+00:00</published>
        <updated>2025-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0109-integrate-early/"/>
        <id>https://bec-systems.com/blog/0109-integrate-early/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0109-integrate-early/">&lt;p&gt;Integration is where we bring together separate parts of a system.&lt;&#x2F;p&gt;
&lt;p&gt;When things come together, problems appear: performance problems, stability
problems, electromagnetic noise issues, mechanical interference,
incompatibilities, manufacturing issues, usability issues, aesthetic issues,
etc.&lt;&#x2F;p&gt;
&lt;p&gt;It is much better to discover these problems early, and the only way to do this
is to integrate everything early in the project. And the only way this happens
is if it is prioritized by management and supported by process.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bradfordembedded.com&#x2F;2012&#x2F;03&#x2F;iterate-hardware-like-software&quot;&gt;Iterate Hardware Like Software&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🕊️ Simple to use vs simple to implement</title>
        <published>2025-01-30T00:00:00+00:00</published>
        <updated>2025-01-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0108-simple-to-use-vs-simple-to-implement/"/>
        <id>https://bec-systems.com/blog/0108-simple-to-use-vs-simple-to-implement/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0108-simple-to-use-vs-simple-to-implement/">&lt;p&gt;To make something simple to use, often it is not simple to implement. For
example, in the SimpleIoT UI, the following line of code is all that is required
to add a text input field to a node. No handlers need to be attached, etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;textInput Point.typeDescription &quot;Description&quot; &quot;&quot;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;However, the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;blob&#x2F;master&#x2F;frontend&#x2F;src&#x2F;UI&#x2F;NodeInputs.elm&quot;&gt;code that implements the textInput&lt;&#x2F;a&gt;
function is a little more involved.&lt;&#x2F;p&gt;
&lt;p&gt;Generally, the better you want the user experience to be (even if your users are
developers using your API or library), the more work you’ll need to put into
things behind the scenes. There is a fundamental tension between “Simple to use”
vs. “Simple to implement” – you can have one or the other – usually not both.
We all use many “components” in product development, but an excessive
off-the-shelf mental, especially at the top hardware and software levels of your
product, won’t get you very far.&lt;&#x2F;p&gt;
&lt;p&gt;Simple != Easy&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤏 Handling the small details</title>
        <published>2025-01-29T00:00:00+00:00</published>
        <updated>2025-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0107-handling-the-small-details/"/>
        <id>https://bec-systems.com/blog/0107-handling-the-small-details/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0107-handling-the-small-details/">&lt;p&gt;We’ve &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0086-keeping-commitments&#x2F;&quot;&gt;discussed&lt;&#x2F;a&gt; the
necessity to fulfill your small commitments as a stepping stone for fulfilling
larger commitments. We can expand this thinking – handling the small details
well enables you to focus on bigger things.&lt;&#x2F;p&gt;
&lt;p&gt;In product development, we have many details to be concerned about:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;consistent code formatting&lt;&#x2F;li&gt;
&lt;li&gt;testing new code&lt;&#x2F;li&gt;
&lt;li&gt;testing the system&lt;&#x2F;li&gt;
&lt;li&gt;ensuring there are no errors or DRC violations on a PCB layout&lt;&#x2F;li&gt;
&lt;li&gt;generating a documentation package (including BOM) for each PCB release&lt;&#x2F;li&gt;
&lt;li&gt;generating documentation for each project release&lt;&#x2F;li&gt;
&lt;li&gt;notifying relevant people when things change&lt;&#x2F;li&gt;
&lt;li&gt;reviewing code changes&lt;&#x2F;li&gt;
&lt;li&gt;organizing parts in the lab and in production&lt;&#x2F;li&gt;
&lt;li&gt;deploying software updates&lt;&#x2F;li&gt;
&lt;li&gt;publishing various communications&lt;&#x2F;li&gt;
&lt;li&gt;ensuring everyone on the team has access to needed information&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can do all of the above manually, and it is not a big deal to do once.
However, these details soon start to pile up until pretty soon that can be all a
person does. Fortunately, there is a better way – all of the above can be
handled to some degree with intelligent workflow, automation, and tooling.&lt;&#x2F;p&gt;
&lt;p&gt;We have so many good options for automation available today – scripting
languages, APIs, CI&#x2F;CD systems, flexible DRC engines in CAD tools, Git based
workflows, commercial tools and services, etc. Implementing and using these
tools is not always easy and requires an investment in time and learning.
However, this is much easier than manually managing tons of details forever and
frees you to focus on more important things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ Selecting tools</title>
        <published>2025-01-28T00:00:00+00:00</published>
        <updated>2025-01-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0106-selecting-tools/"/>
        <id>https://bec-systems.com/blog/0106-selecting-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0106-selecting-tools/">&lt;p&gt;There are many considerations when selecting a tool:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;will it do the job?&lt;&#x2F;li&gt;
&lt;li&gt;what does it cost?&lt;&#x2F;li&gt;
&lt;li&gt;can I get support?&lt;&#x2F;li&gt;
&lt;li&gt;is there a community around it?&lt;&#x2F;li&gt;
&lt;li&gt;will it be available and maintained long-term?&lt;&#x2F;li&gt;
&lt;li&gt;what does the future look like for new features?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;is it accessible&#x2F;available to others?&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The last point is often overlooked – “That is not my problem.” However, if you
are building a platform, this should be a primary consideration as tool
accessibility is important for collaboration and maintenance. This is the
difference between a sustainable business and a few talented individuals.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛠️ Two classes of tools</title>
        <published>2025-01-27T00:00:00+00:00</published>
        <updated>2025-01-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0105-two-classes-of-tools/"/>
        <id>https://bec-systems.com/blog/0105-two-classes-of-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0105-two-classes-of-tools/">&lt;p&gt;There are two classes of tools: &lt;strong&gt;Personal&lt;&#x2F;strong&gt; tools and &lt;strong&gt;Common&lt;&#x2F;strong&gt; tools.&lt;&#x2F;p&gt;
&lt;p&gt;A personal tool might be your editor – each developer has his own preferences
and what editor one person uses does not affect another.&lt;&#x2F;p&gt;
&lt;p&gt;However, it is important to have a common tool for formatting code. So you
decide on a formatting tool and everyone configures their editor to use that.&lt;&#x2F;p&gt;
&lt;p&gt;Some more examples:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Personal&lt;&#x2F;th&gt;&lt;th&gt;Common&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Computer OS&lt;&#x2F;td&gt;&lt;td&gt;File&#x2F;doc formats&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Phone&lt;&#x2F;td&gt;&lt;td&gt;Git PR&#x2F;Issue system&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Notes system&lt;&#x2F;td&gt;&lt;td&gt;Build systems&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Email client&lt;&#x2F;td&gt;&lt;td&gt;CI&#x2F;CD&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Browser&lt;&#x2F;td&gt;&lt;td&gt;CAD Tools&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Git client&#x2F;setup&lt;&#x2F;td&gt;&lt;td&gt;Compilers&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Sometimes sticking with the common stuff is slightly less convenient than doing
it “my way.” However, you need to decide if you want to be part of a sustainable
business or just a few talented individuals.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 Documentation is part of the process, not an afterthought</title>
        <published>2025-01-24T00:00:00+00:00</published>
        <updated>2025-01-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0104-documentation-is-part-of-the-process-not-an-afterthought/"/>
        <id>https://bec-systems.com/blog/0104-documentation-is-part-of-the-process-not-an-afterthought/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0104-documentation-is-part-of-the-process-not-an-afterthought/">&lt;p&gt;One of the best productivity hacks ever is to change your thinking about
documentation. Most documentation is done after the fact, which is a rather
distasteful task at this phase.&lt;&#x2F;p&gt;
&lt;p&gt;If we learn to use documentation as part of our thinking&#x2F;design&#x2F;implementation
process, it can be enjoyable, and help us do a better job in the first place. A
few ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Write code comments before we write the code, describe what we are going to
do, etc.&lt;&#x2F;li&gt;
&lt;li&gt;In a schematic, document constraints and design criteria as a note in the
schematic before drawing a new section of the schematic. As you go, think in
your notes.&lt;&#x2F;li&gt;
&lt;li&gt;Write the user documentation before implementing a feature – this may help us
think more from the user perspective upfront.&lt;&#x2F;li&gt;
&lt;li&gt;If we are stuck on a problem, write documentation about it and check it into
Git. This allows us to still
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0098-thinking-designing-developing-engineering&#x2F;&quot;&gt;ship something&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;As we are doing something, create careful notes about all the resources we
need to do the job, summarize important parts with screenshots, etc. It will
be much easier next time.&lt;&#x2F;li&gt;
&lt;li&gt;Create a checklist before you do something.&lt;&#x2F;li&gt;
&lt;li&gt;When someone asks you about something, instead of writing an answer in an
email, create a document and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0096-effective-email-is-either-a-pointer-or-notification&#x2F;&quot;&gt;point them do it&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A small shift in our habits can have a big impact!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✨ Demos vs. Products</title>
        <published>2025-01-23T00:00:00+00:00</published>
        <updated>2025-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0103-demos-vs-products/"/>
        <id>https://bec-systems.com/blog/0103-demos-vs-products/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0103-demos-vs-products/">&lt;p&gt;I’m a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;020&#x2F;&quot;&gt;huge fan&lt;&#x2F;a&gt; of demos –
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;daily.himvis.com&#x2F;0088-power-of-demo&#x2F;&quot;&gt;so is Khem&lt;&#x2F;a&gt;. They are a very
important part of product development. They are a way to ship early and get
critical feedback. Demos during the course of real product development are
essential.&lt;&#x2F;p&gt;
&lt;p&gt;There are some challenges or risks with demos. One is that when managers see a
demo, they sometimes assume the product is nearly done when this is rarely the
case.&lt;&#x2F;p&gt;
&lt;p&gt;Other demos are for the purpose of evaluating some technology with little
concern as to how it is implemented. The world has exploded with “maker” stuff
(Arduinos, Raspberry PIs, etc). These are very useful for one-off lab
experiments, but experience has taught me that it is generally a bad idea to
ship products (at least industrial products) based on “maker” technology.&lt;&#x2F;p&gt;
&lt;p&gt;Products have considerations like cost, manufacturability, maintainability,
reliability, and availability over a lifecycle that can be 5, 10, or more years
for industrial products. We can ignore these concerns for the demo, but they
can’t be ignored for the product.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧩 The three legs of YOUR Platform</title>
        <published>2025-01-22T00:00:00+00:00</published>
        <updated>2025-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0102-the-three-legs-of-your-platform/"/>
        <id>https://bec-systems.com/blog/0102-the-three-legs-of-your-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0102-the-three-legs-of-your-platform/">&lt;p&gt;&lt;strong&gt;Automation&lt;&#x2F;strong&gt; – start with a checklist.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Collaboration&lt;&#x2F;strong&gt; – #1 rule is don’t view email as a permanent place to store
information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Process&lt;&#x2F;strong&gt; – the habits of your organization.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 The importance of small Git commits&#x2F;pull-requests</title>
        <published>2025-01-21T00:00:00+00:00</published>
        <updated>2025-01-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0101-the-importance-of-small-git-commits-pull-requests/"/>
        <id>https://bec-systems.com/blog/0101-the-importance-of-small-git-commits-pull-requests/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0101-the-importance-of-small-git-commits-pull-requests/">&lt;p&gt;Why are small Git commits&#x2F;pull-requests important?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;small changes are easier to review. Large PRs are painful to review, thus
they tend to be rubber-stamped and not reviewed, or rejected in OSS projects.&lt;&#x2F;li&gt;
&lt;li&gt;you get to
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0099-the-importance-of-git-commit-push-often&#x2F;&quot;&gt;ship more often&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;other people are motivated by seeing work get done (positive peer pressure).&lt;&#x2F;li&gt;
&lt;li&gt;if we are heading down the wrong path, this can be corrected earlier before
wasting a lot of time.&lt;&#x2F;li&gt;
&lt;li&gt;our work is more transparent, and transparency is a powerful tool.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Even if we are working on a personal project that no one else sees, small
commits helps us organize our thoughts, reflect on what we’ve done, and receive
the motivation boost that comes from incrementally shipping, even if only to
ourself.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎆 100 daily emails</title>
        <published>2025-01-20T00:00:00+00:00</published>
        <updated>2025-01-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0100-100-daily-emails/"/>
        <id>https://bec-systems.com/blog/0100-100-daily-emails/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0100-100-daily-emails/">&lt;p&gt;Today marks the 100th “daily” email I’ve sent out. (I don’t actually send on
weekends, or days when I’m out of the office). Some observations:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Daily is easier than weekly – I was skeptical when others said this, but I
think it is true.&lt;&#x2F;li&gt;
&lt;li&gt;If I skip a few days, it can be hard to get going again. There is something
about the process of doing something daily that energizes the creative
process and keeps it going.&lt;&#x2F;li&gt;
&lt;li&gt;Ideas are everywhere – when I write consistently, the mind starts to see
ideas everywhere. There are 32 article ideas in my backlog – Ideas come in
much faster than they go out.&lt;&#x2F;li&gt;
&lt;li&gt;I spend 10-20 minutes a day writing these posts. Often writing one will spur
the idea for the next, and I’ll write that one too. I think it could be even
faster.&lt;&#x2F;li&gt;
&lt;li&gt;Tooling is important. I have scripts that automate creating a post and
publishing it. Kit is configured to pick up the post from my site’s RSS feed
and then mail it out. There is nothing slow or painful about the process that
pushes me away from doing it.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If you have feedback, please let me know! I’d love to know what topics are
interesting to you or not.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔁 The importance of Git Commit&#x2F;Push often</title>
        <published>2025-01-15T00:00:00+00:00</published>
        <updated>2025-01-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0099-the-importance-of-git-commit-push-often/"/>
        <id>https://bec-systems.com/blog/0099-the-importance-of-git-commit-push-often/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0099-the-importance-of-git-commit-push-often/">&lt;p&gt;There are many forms of “shipping” your work as we
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0098-thinking-designing-developing-engineering&#x2F;&quot;&gt;recently discussed&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Shipping does not necessarily mean a product release, but rather releasing your
work external to you. It can be a Git push, running tests in CI, a prototype, a
document that others can read – basically something of &lt;strong&gt;&lt;em&gt;lasting value&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; that
others can interact with. (Email does not count).&lt;&#x2F;p&gt;
&lt;p&gt;As a developer, the simplest way to ship your work is a Git push. It does not
have to be perfect. In most cases, it does not even have to be done. That is the
beauty of software, it is soft – it can be improved&#x2F;finished later. A Git
commit does not even have to be code – it can be documentation, specs, etc. A
Git commit&#x2F;push is the simplest and most effective way to demonstrate you are
providing value to the project or organization. Yet how many of us are consumed
with ephemeral activities that in the end provide no lasting value?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💭 Thinking, Designing, Developing, Engineering ...</title>
        <published>2025-01-13T00:00:00+00:00</published>
        <updated>2025-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0098-thinking-designing-developing-engineering/"/>
        <id>https://bec-systems.com/blog/0098-thinking-designing-developing-engineering/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0098-thinking-designing-developing-engineering/">&lt;p&gt;If we are thinking without writing, are we really thinking?&lt;&#x2F;p&gt;
&lt;p&gt;If we are designing without sketching&#x2F;drawing, are we really designing?&lt;&#x2F;p&gt;
&lt;p&gt;If we are developing software without iterations&#x2F;testing, are we really
developing?&lt;&#x2F;p&gt;
&lt;p&gt;If we are engineering without building prototypes, are we really engineering?&lt;&#x2F;p&gt;
&lt;p&gt;Something happens when our work is implemented in an external form that is
staring back at us. It speaks to us, exposes the flaws, and shows us where
improvements are possible. When our work is good, we can recognize it and find
motivation for the next phase.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, it is possible to do some things without shipping, but when we ship our
work in the form of writing, drawing, prototyping, and iterating, a world opens
up that we could never see before. New connections are made.&lt;&#x2F;p&gt;
&lt;p&gt;Optimize your habits&#x2F;processes for shipping something – your work will get
better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 envsetup.sh -- a very useful automation technique</title>
        <published>2025-01-10T00:00:00+00:00</published>
        <updated>2025-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0097-envsetup-sh-a-very-useful-automation-technique/"/>
        <id>https://bec-systems.com/blog/0097-envsetup-sh-a-very-useful-automation-technique/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0097-envsetup-sh-a-very-useful-automation-technique/">&lt;p&gt;During a Android development stint, I learned about the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;what-is-this-history-of-envset-gMmZ_weeQueW5i8TIrKDHA&quot;&gt;&lt;code&gt;envsetup.sh&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
concept. This is a script that contains numerous functions get populated in a
shell envrionment when the script is sourced. There two ways to source the file
– you can type:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;source envsetup.sh&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Or use a ‘.’ for a shortcut for source and type:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;. envsetup.sh&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Most of my projects and Git repos now contain a &lt;code&gt;envsetup.sh&lt;&#x2F;code&gt; file (examples:
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;blob&#x2F;master&#x2F;envsetup.sh&quot;&gt;Simple IoT&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;envsetup.sh&quot;&gt;Yoe&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;tmpdir&#x2F;tmpdir.org&#x2F;-&#x2F;blob&#x2F;master&#x2F;envsetup.sh&quot;&gt;TMPDIR Podcast&lt;&#x2F;a&gt;).
Typically all of the functions in the file have a common prefix. This gives them
a namespace and allows you to see all the functions quickly in your terminal by
typing &lt;code&gt;&amp;lt;prefix&amp;gt;&amp;lt;tab&amp;gt;&amp;lt;tab&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Why shell functions instead of something like Make, Earthly, Nix, Task, Mage,
Pants, Bazel, Python …? Shell script is about the simplest abstraction on top
of typing commands. Thus, if mostly what you need to do is execute a sequence of
terminal commands, then shell functions are very efficient at doing this. A
shell function is often the best documentation for how to do something – it is
almost like a powerful checklist. There are no dependencies – every Linux and
MacOS system comes with a shell built-in. &lt;code&gt;envsetup.sh&lt;&#x2F;code&gt; functions can often be
used directly in CI&#x2F;CD and other build systems (like Yocto&#x2F;Bitbake tasks).&lt;&#x2F;p&gt;
&lt;p&gt;There are some common objections …&lt;&#x2F;p&gt;
&lt;p&gt;Shell is not cross-platform to Windows. That is unfortunate, but I rarely use
Windows, and most developers I interact with use either Linux or MacOS systems.
However, this may change with Zephyr as MCU developers traditionally have used
Windows.&lt;&#x2F;p&gt;
&lt;p&gt;Why not use something more powerful like Make? With modern programming languages
and build systems like Go, Rust, and Yocto, the is no need for yet another build
system. The complex issues like dependencies are already handled. Thus, all you
need to do is remember how to kick it off.&lt;&#x2F;p&gt;
&lt;p&gt;Why not use Python – everyone uses Python for everything – it is the most
popular programming language ever! Python is great if you need to do something
more complex, but it is a more complex programming abstraction. And mostly what
you need to do is record a sequence of commands, any abstraction costs you more
than benefits.&lt;&#x2F;p&gt;
&lt;p&gt;Why not a shell script that you execute instead of sourcing a script that
populates functions? I’m not sure – the sourcing just seems more ergonomic to
me and simpler. If you need to run a script to execute a command, then you need
to process command line arguments, etc. You are now programming, and programming
is what we are trying to avoid in &lt;code&gt;envsetup.sh.&lt;&#x2F;code&gt; Also, the functions are not as
discoverable as when they are populated in your environment.&lt;&#x2F;p&gt;
&lt;p&gt;Shell scripting is not without its tradeoffs – when you do need to program
something in shell, it can be very painful and errors can be subtle and hard to
catch. However, AI tools are very effective at writing shell script, so this can
be a big help. Linters and formatters are also very good at catching problems
early and making your scripts more readable (more on this later).&lt;&#x2F;p&gt;
&lt;p&gt;In summary, think of your &lt;code&gt;envsetup.sh&lt;&#x2F;code&gt; file primarily as documentation. Create
one in every project and instead of documentation how to do something, create a
shell function. Your future self will thank you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📧 Effective email is either a pointer or notification</title>
        <published>2025-01-08T00:00:00+00:00</published>
        <updated>2025-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0096-effective-email-is-either-a-pointer-or-notification/"/>
        <id>https://bec-systems.com/blog/0096-effective-email-is-either-a-pointer-or-notification/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0096-effective-email-is-either-a-pointer-or-notification/">&lt;p&gt;Email is the only decentralized communication platform that has widespread
usage. And this is more amazing considering it was invented in 1971. Email is an
amazing technology and has stood the test of time.&lt;&#x2F;p&gt;
&lt;p&gt;However, there are challenges with email:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It can be difficult to find information in emails at a later date.&lt;&#x2F;li&gt;
&lt;li&gt;Visibility is limited to the recipes of the email.&lt;&#x2F;li&gt;
&lt;li&gt;Discussions often don’t happen in the context of the work being done.&lt;&#x2F;li&gt;
&lt;li&gt;Information is not organized very well.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I follow a few rules regarding email:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Whenever possible, don’t send information in email, but rather point people to
information in a more permanent location (Git repo, Wiki, Discourse forum,
etc.). If the information does not exist, create it, and then send the email.&lt;&#x2F;li&gt;
&lt;li&gt;Keep project-related discussions in Git pull requests, issues, forums, etc.&lt;&#x2F;li&gt;
&lt;li&gt;For transient discussions, use chat tools like Discourse chat, Signal,
Discord, Slack, etc. This is more fun, and keeps email from clogging up with
chatty stuff. This keeps the information accessible to everyone involved. It
is also way more efficient as discussions and information are stored in the
context of the work.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is still very useful to receive email notifications when a piece of
information or a discussion is updated. This is quick to process and gives
everyone interested the opportunity to watch the stream of activity as it flows
by. Most systems give you options for tuning how many email notifications you
receive based on your time&#x2F;interest.&lt;&#x2F;p&gt;
&lt;p&gt;Accessibility and context – the keys to effective communication and
information.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎓 The problem with experts</title>
        <published>2025-01-07T00:00:00+00:00</published>
        <updated>2025-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0095-the-problem-with-experts/"/>
        <id>https://bec-systems.com/blog/0095-the-problem-with-experts/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0095-the-problem-with-experts/">&lt;p&gt;At a recent family holiday gathering, we happened to be discussing how crazy
family life gets at times – you are halfway through cooking something and
realize you don’t have the ingredients on hand, so you need to improvise. Some
of the men in the group described how they always get everything out first
before starting, which ironically
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0094-preparation-lessons-from-the-kitchen&#x2F;&quot;&gt;I also do&lt;&#x2F;a&gt;.
Some of the females commented this was unnecessary as they had done it thousands
of times, so it was easier to get stuff as needed. They have a pretty good sense
of where stuff is and what they have on hand – 99.9% of the time it works
pretty well.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps this is a general difference between men and women – women are
generally better at multitasking. But I think there is also another factor at
play – with food preparation, the women in our families are experts, and the
men are amateurs. Experts are very good at what they do. They don’t need a
process to prop them up. However, in the cooking example it is more difficult to
scale these methods to their husbands or children.&lt;&#x2F;p&gt;
&lt;p&gt;The real value in expertise is in scaling it. Do we document what we do? Can we
make it easy for others to follow? Can we make it easy to find the things we
need? Can we create processes that reduce errors and blockers? In the kitchen,
these differences between the amateurs and experts are mostly amusing and not
all that critical, but in business and product development it is. Experts need
to be creating and contributing to platforms. This is the difference between a
sustainable business and a few talented individuals. Unfortunately, many experts
don’t personally feel they need a platform, so have little motivation to
contribute to one.&lt;&#x2F;p&gt;
&lt;p&gt;When you hire, expertise is important, but so is Platform Thinking.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🍳 Preparation - lessons from the kitchen</title>
        <published>2025-01-06T00:00:00+00:00</published>
        <updated>2025-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0094-preparation-lessons-from-the-kitchen/"/>
        <id>https://bec-systems.com/blog/0094-preparation-lessons-from-the-kitchen/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0094-preparation-lessons-from-the-kitchen/">&lt;p&gt;Most Sunday mornings, I make gluten-free waffles for breakfast (see recipe at
the end of this post). I like to get everything out (ingredients and utensils)
before I start.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;0&#x2F;0a0dfc7f57c40b138df10008b17933f83b0b167a.jpeg&quot; alt=&quot;prep&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This seems to make the process go faster and smoother. There is an efficiency in
focusing on getting everything first, and then cooking.&lt;&#x2F;p&gt;
&lt;p&gt;So I was wondering if there is an analogy to product development. What are the
ingredients for product development?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;clear definition of the goal and next steps&lt;&#x2F;li&gt;
&lt;li&gt;any relevant documentation&lt;&#x2F;li&gt;
&lt;li&gt;tools (editor, CAD tool, issue tracking systems, build systems, tests,
release processes, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;collaboration with others on the team (issues, PRs, discussions, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Is this scattered all over the place, or can you quickly assemble all of this
and hit the ground running?&lt;&#x2F;p&gt;
&lt;p&gt;It helps to
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;habit-note-taking-while-working-on-a-task&#x2F;601&quot;&gt;organize your work in a notes system&lt;&#x2F;a&gt;.
This has links to relevant information and notes so you immediately have all the
relevant context.&lt;&#x2F;p&gt;
&lt;p&gt;For some tasks like code review, tools can prepare the task for us.
Github&#x2F;Gitea&#x2F;Gitlab pull request (PR) workflows have the code, discussion, and
proposed changes all in one place.&lt;&#x2F;p&gt;
&lt;p&gt;With any task, having all the ingredients at hand makes for a nice result!
Preparation leads to focus.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;f&#x2F;fc87021d485b91e47c14a6e5f2536e6135015bd9.jpeg&quot; alt=&quot;waffles&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Gluten-free waffle recipe:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;1&#x2F;14d4be6673b848cfb619a83c41edcf477c46d121.png&quot; alt=&quot;waffle recipe&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😊 Joy</title>
        <published>2025-01-03T00:00:00+00:00</published>
        <updated>2025-01-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0093-joy/"/>
        <id>https://bec-systems.com/blog/0093-joy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0093-joy/">&lt;p&gt;Platforms help bring the joy back into engineering.&lt;&#x2F;p&gt;
&lt;p&gt;How? – by assisting you with the tedious error-prone tasks, and freeing you to
focus on the valuable creative work.&lt;&#x2F;p&gt;
&lt;p&gt;Satisfaction comes from being useful and creating value. We need to get to the
place where we can do that work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🪞 Platform reflection</title>
        <published>2025-01-02T00:00:00+00:00</published>
        <updated>2025-01-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0092-platform-reflection/"/>
        <id>https://bec-systems.com/blog/0092-platform-reflection/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0092-platform-reflection/">&lt;p&gt;How has YOUR Platform done this past year?&lt;&#x2F;p&gt;
&lt;p&gt;Have you burned down technical debt?&lt;&#x2F;p&gt;
&lt;p&gt;Have you automated repetitious or tedious tasks?&lt;&#x2F;p&gt;
&lt;p&gt;Is your test coverage increasing or decreasing?&lt;&#x2F;p&gt;
&lt;p&gt;Are you releasing more often?&lt;&#x2F;p&gt;
&lt;p&gt;Are deployments getting easier?&lt;&#x2F;p&gt;
&lt;p&gt;Are you deploying with more confidence?&lt;&#x2F;p&gt;
&lt;p&gt;Is your documentation getting better?&lt;&#x2F;p&gt;
&lt;p&gt;Is it easier for new people to get up to speed?&lt;&#x2F;p&gt;
&lt;p&gt;Do you have any new checklists?&lt;&#x2F;p&gt;
&lt;p&gt;Have any existing checklists been automated?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🙏 Humility</title>
        <published>2024-12-27T00:00:00+00:00</published>
        <updated>2024-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0091-humility/"/>
        <id>https://bec-systems.com/blog/0091-humility/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0091-humility/">&lt;p&gt;An essential mindset for platform thinking is humility – the realization that
we as humans are finite, we make mistakes, we don’t always perform at the same
level, we get lazy and tend to take shortcuts.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform can compensate for much of this as it does the boring tedious
work, checks for mistakes, deploys reliably, provides structure, etc.&lt;&#x2F;p&gt;
&lt;p&gt;But we need to acknowledge this first, and that is the first step.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 The biggest benefit to frequent updates</title>
        <published>2024-12-23T00:00:00+00:00</published>
        <updated>2024-12-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0090-the-biggest-benefit-to-frequent-updates/"/>
        <id>https://bec-systems.com/blog/0090-the-biggest-benefit-to-frequent-updates/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0090-the-biggest-benefit-to-frequent-updates/">&lt;p&gt;Perhaps the biggest benefit of frequent updates is that the changes are small,
making them easier for humans to absorb and adapt to.&lt;&#x2F;p&gt;
&lt;p&gt;The conventional wisdom in our industry is that frequent updates mean things are
always breaking. This has not been my experience; rather, things are
continuously improving in small ways, and the changes are much easier to adapt
to.&lt;&#x2F;p&gt;
&lt;p&gt;Arch Linux is a classic example – always improving, rarely breaks, and when it
does, you can usually find a fix in a few minutes. Zephyr is another example –
always improving, and rarely problems merging in the new changes.&lt;&#x2F;p&gt;
&lt;p&gt;When things break or change unexpectedly, you are only dealing with one issue at
a time, not dozens or even hundreds.&lt;&#x2F;p&gt;
&lt;p&gt;This is more organic and enjoyable – the way natural systems work. Small
continuous changes (either good or bad) are better than large step changes and
much easier on the system.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📅 Dates in filenames</title>
        <published>2024-12-20T00:00:00+00:00</published>
        <updated>2024-12-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0089-dates-in-filenames/"/>
        <id>https://bec-systems.com/blog/0089-dates-in-filenames/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0089-dates-in-filenames/">&lt;p&gt;One of the most common labels we use today is dates. We use them in file names,
reports, database fields, etc. There are many ways to enter a date:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;2024-12-20&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;20 Dec 24&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;12&#x2F;20&#x2F;2024&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;20&#x2F;12&#x2F;2024&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Dec 20, 2024&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3339&quot;&gt;RFC 3339&lt;&#x2F;a&gt; (&lt;code&gt;YYYY-MM-DDTHH:MM:SS+HH:MM&lt;&#x2F;code&gt;)
is increasingly becoming an international standard. Many programming languages
(Go, Rust, Javascript, Elm) support RFC 3339.&lt;&#x2F;p&gt;
&lt;p&gt;What about when naming files? It is often helpful to put a date in directory or
file names so you can easily sort to find the latest or construct a timeline of
events. In this case it makes sense to format the date
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0052-how-do-you-consistently-name-things&#x2F;&quot;&gt;general to specific&lt;&#x2F;a&gt;
YYYY-MM-DD and put the date at the beginning of the filename:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;2024-10-20_project-requirements.docx&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;2023-11-01_architecture-rev1.pdf&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;2024-11-11_architecture-rev2.pdf&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;2024-12-15_release-v1&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With a little thought, even simple things like file and directory names can
become useful metadata that is easy to sort and query. Consistency and standards
– simple things you can do to make things better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Lifecycle management in dynamic systems</title>
        <published>2024-12-18T00:00:00+00:00</published>
        <updated>2024-12-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0088-lifecycle-management-in-dynamic-systems/"/>
        <id>https://bec-systems.com/blog/0088-lifecycle-management-in-dynamic-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0088-lifecycle-management-in-dynamic-systems/">&lt;p&gt;One of the hard parts of dynamic systems is the lifecycle management of various
bits of running code.&lt;&#x2F;p&gt;
&lt;p&gt;It is easy to create stuff, but are you cleaning up properly when things
disappear or change?&lt;&#x2F;p&gt;
&lt;p&gt;We can order these in difficulty:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Create something: (easy)&lt;&#x2F;li&gt;
&lt;li&gt;Delete something: (hard)&lt;&#x2F;li&gt;
&lt;li&gt;Change something already running: (very hard)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On the surface, this looks easy – what is the big deal, right?&lt;&#x2F;p&gt;
&lt;p&gt;But we soon realize differently. Have you ever heard of memory&#x2F;resource leaks
and race conditions? Even worse, code that we don’t know is still running.&lt;&#x2F;p&gt;
&lt;p&gt;Implementations usually start simple – no problem.&lt;&#x2F;p&gt;
&lt;p&gt;But the scope grows, the system becomes more dynamic, and we start to scale.
Scaling requires concurrency. Concurrency is hard, but when the system changes
while running, concurrency gets really hard.&lt;&#x2F;p&gt;
&lt;p&gt;This is the nature of IoT systems – because they reflect the real world, and
the real world is always changing.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧪 Abstractions and Platforms</title>
        <published>2024-12-17T00:00:00+00:00</published>
        <updated>2024-12-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0087-abstractions-and-platforms/"/>
        <id>https://bec-systems.com/blog/0087-abstractions-and-platforms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0087-abstractions-and-platforms/">&lt;p&gt;I’ve come to appreciate the Go communities advice on abstractions.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Avoid creating abstractions prematurely. Every abstraction has a cost, and
often duplicated code is simpler and easier to maintain than a premature
abstraction.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Don’t take DRY (Don’t Repeat Yourself) to an extreme. It is perfectly fine to
duplicate code several times and only create an abstraction once you see a clear
pattern and understand better the problem the abstraction is solving.&lt;&#x2F;p&gt;
&lt;p&gt;For instance, in Simple IoT, we implemented a number of subsystems (rules,
modbus, 1-wire, etc.) before we noticed a pattern – all of these systems needed
lifecycle management, which is very tricky to get right. So it made sense to
create a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot@v0.18.1&#x2F;client#Client&quot;&gt;client abstraction&lt;&#x2F;a&gt;
that handled lifecycle in one place. But it was not clear what we really needed
until we had implemented several subsystems.&lt;&#x2F;p&gt;
&lt;p&gt;Follow the YAGNI (You Ain’t Gonna Need It) principle – only create abstractions
when you need them, not for hypothetical future use cases.&lt;&#x2F;p&gt;
&lt;p&gt;The same applies to platforms.&lt;&#x2F;p&gt;
&lt;p&gt;Other than avoiding architectural pitfalls and selecting the wrong technology,
focus on building out YOUR Platform to solve your current needs, not your future
needs. This is one of the best ways to know if your architecture and technology
are right.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms for the sake of platforms are detrimental and counter-productive –
kind of like the IT department that loses its focus that they are there to serve
the business needs and becomes a barrier to getting things done. They must serve
the business goals, not themselves.&lt;&#x2F;p&gt;
&lt;p&gt;A platform in itself provides no value if you are not shipping something of
value.&lt;&#x2F;p&gt;
&lt;p&gt;The same can be said of any supporting role or metric – finance, performance,
etc.&lt;&#x2F;p&gt;
&lt;p&gt;If you are not shipping (internal prototypes and test versions count as
shipping), nothing else matters.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 Keeping commitments</title>
        <published>2024-12-16T00:00:00+00:00</published>
        <updated>2024-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0086-keeping-commitments/"/>
        <id>https://bec-systems.com/blog/0086-keeping-commitments/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0086-keeping-commitments/">&lt;p&gt;When we commit to something, do we follow through? How do we get better at this
when we always have more to do than time to do it?&lt;&#x2F;p&gt;
&lt;p&gt;The thought came recently that it probably starts with keeping commitments to
ourselves, which is the essence of self-discipline. If we can’t keep promises to
ourselves, likely we won’t keep them to others either.&lt;&#x2F;p&gt;
&lt;p&gt;If we plan to get up at 6 AM, do we?&lt;&#x2F;p&gt;
&lt;p&gt;If we plan to walk every day, do we?&lt;&#x2F;p&gt;
&lt;p&gt;If we plan to work on something today, do we block out the time and make it
happen?&lt;&#x2F;p&gt;
&lt;p&gt;Seemingly simple things, but important and sometimes hard in this busy life.&lt;&#x2F;p&gt;
&lt;p&gt;If we can’t do the small things, we’ll likely not succeed in the bigger things.&lt;&#x2F;p&gt;
&lt;p&gt;This is foundational in Platform Thinking – at the personal, group, or
organization level. If you do the small things right, this will enable you to do
the big things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📝 Personal vs. collaborative documentation</title>
        <published>2024-12-13T00:00:00+00:00</published>
        <updated>2024-12-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0085-personal-vs-collaborative-documentation/"/>
        <id>https://bec-systems.com/blog/0085-personal-vs-collaborative-documentation/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0085-personal-vs-collaborative-documentation/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0084-what-is-your-most-important-tool&#x2F;&quot;&gt;Yesterday&lt;&#x2F;a&gt;,
we discussed the importance of a personal note-taking tool. We can also extend
this concept to a team or company using Wikis, Markdown in Git, shared Google
Docs, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Collaborative documentation is very valuable – IF you can get group
participation. Over the years at various companies, I’ve set up Wikis as
collaborative documentation efforts. Most of them resulted in only me
contributing. Group initiatives like this need to come from the top, otherwise
there is very little incentive for people to contribute. As a result, I’ve
pretty much given up on Wikis for small teams&#x2F;companies – it is nearly
impossible to get momentum and maintain the information. This is sad because so
much knowledge is lost and effort wasted as the same things are rehashed,
relearned, and re-communicated.&lt;&#x2F;p&gt;
&lt;p&gt;As a result, I now focus primarily on:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;My own personal notes system&lt;&#x2F;li&gt;
&lt;li&gt;Markdown in project Git repos&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If I’m going to be the only one creating and reading notes, it may as well be in
my own personal notes system which is most convenient for me.&lt;&#x2F;p&gt;
&lt;p&gt;For project documentation, this is best maintained in the Git repo as close as
possible to the source code or design files. There it has a better chance of
documentation being maintained if it is worked into the PR workflow and review
process.&lt;&#x2F;p&gt;
&lt;p&gt;In the course of product development, documentation is the hardest deliverable
to produce because its effects are hard to measure. Initially, the product still
functions without documentation. Documentation costs short-term but produces
compounding gains long-term. It is an investment in the future. If your team or
organization is not interested in making this investment, you can always make it
personally.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 What is your most important tool?</title>
        <published>2024-12-12T00:00:00+00:00</published>
        <updated>2024-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0084-what-is-your-most-important-tool/"/>
        <id>https://bec-systems.com/blog/0084-what-is-your-most-important-tool/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0084-what-is-your-most-important-tool/">&lt;p&gt;Your editor? Your CAD tool? Your 2GHz oscilloscope? Your phone? Your computer?&lt;&#x2F;p&gt;
&lt;p&gt;In the information age, we are flooded with information and opportunities.&lt;&#x2F;p&gt;
&lt;p&gt;Many of the problems we solve are ones we’ve never seen before, or at least not
very often.&lt;&#x2F;p&gt;
&lt;p&gt;Most of us have more to do than we can ever hope to get done in multiple
lifetimes.&lt;&#x2F;p&gt;
&lt;p&gt;We are exposed to way more knowledge than we can ever fit in our finite
memories. Therefore, a tool to efficiently capture, organize, and find your
personal knowledge may be your most important tool.&lt;&#x2F;p&gt;
&lt;p&gt;If we figure out something, we can make a note so we don’t have to figure it out
again the next time.&lt;&#x2F;p&gt;
&lt;p&gt;If we repeatedly do something that requires multiple steps, a checklist can make
this easier.&lt;&#x2F;p&gt;
&lt;p&gt;If we learn something valuable, a note makes this useful in the future.&lt;&#x2F;p&gt;
&lt;p&gt;Creating notes encourages reflection.&lt;&#x2F;p&gt;
&lt;p&gt;With a good notes system, we can organize and prioritize what we do.&lt;&#x2F;p&gt;
&lt;p&gt;Over time this helps build a picture or model of what we know and have
experienced. This model helps us leverage what we have done in the past in the
future.&lt;&#x2F;p&gt;
&lt;p&gt;There are many good notetaking tools and methods (Notion, Workflowy, Logseq,
Bullet Journal, etc.) so there is very likely one that will fit you. Some things
I look for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;low friction to use&lt;&#x2F;li&gt;
&lt;li&gt;stores text and images&lt;&#x2F;li&gt;
&lt;li&gt;can be used on multiple mobile and desktop platforms&lt;&#x2F;li&gt;
&lt;li&gt;can export the information so that it can be moved to another system if
necessary&lt;&#x2F;li&gt;
&lt;li&gt;has a stable history and likely future – something you can use for 5-10+
years&lt;&#x2F;li&gt;
&lt;li&gt;easy to share information with others&lt;&#x2F;li&gt;
&lt;li&gt;and most importantly – you own the information and can take it with you. IE,
don’t store your personal knowledge base in your employer’s MS Teams OneNote
app.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Workflowy has been perfect for me, but there are lots of other good options.&lt;&#x2F;p&gt;
&lt;p&gt;Over time your personal notetaking tool becomes a valuable knowledge base that
you can take with you anywhere you go – part of YOUR
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;#personal&quot;&gt;Personal&lt;&#x2F;a&gt; Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📧 Inbox zero</title>
        <published>2024-12-11T00:00:00+00:00</published>
        <updated>2024-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0083-inbox-zero/"/>
        <id>https://bec-systems.com/blog/0083-inbox-zero/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0083-inbox-zero/">&lt;p&gt;Thanks to a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;daily.himvis.com&#x2F;0065-zero-inbox-rule&#x2F;&quot;&gt;nudge from Khem&lt;&#x2F;a&gt;,
I’m back to Inbox-zero.&lt;&#x2F;p&gt;
&lt;p&gt;The big question is what to do with emails that need action or have valuable
information in them? Some put them in a special folder. Others tag them. Others
forward them to lots of people.&lt;&#x2F;p&gt;
&lt;p&gt;The best solution is to move the action or information to another system such as
a project ticketing system, or Workflowy (my personal notes system). I then
archive the email and dig it out of the archive if I need to reply later.&lt;&#x2F;p&gt;
&lt;p&gt;Email is a great notification system, but it does not work very well at the
following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;collaboration&lt;&#x2F;li&gt;
&lt;li&gt;knowledge capture&lt;&#x2F;li&gt;
&lt;li&gt;workflow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Find other solutions for the above such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Github&#x2F;Gitea&#x2F;Gitlab issues, projects, wikis, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Markdown in Git is a great way to capture knowledge from emails&lt;&#x2F;li&gt;
&lt;li&gt;Trello&lt;&#x2F;li&gt;
&lt;li&gt;Personal notes system&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Collaboration, knowledge capture, open access to knowledge, and workflow are key
components of YOUR Platform. Getting information out of email is critical, and
following an Inbox-zero policy is a great way to help make this happen.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏆 Goals vs. Systems</title>
        <published>2024-12-10T00:00:00+00:00</published>
        <updated>2024-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0082-goals-vs-systems/"/>
        <id>https://bec-systems.com/blog/0082-goals-vs-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0082-goals-vs-systems/">&lt;blockquote&gt;
&lt;p&gt;“You do not rise to the level of your goals. You fall to the level of your
systems.” – James Clear, Atomic Habits&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Goals and vision are important, but we also need a way to get there.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏁 Easy to start vs. easy to finish</title>
        <published>2024-12-09T00:00:00+00:00</published>
        <updated>2024-12-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0081-easy-to-start-vs-easy-to-finish/"/>
        <id>https://bec-systems.com/blog/0081-easy-to-start-vs-easy-to-finish/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0081-easy-to-start-vs-easy-to-finish/">&lt;p&gt;There are many ways to classify how we do things. One way is “easy to start” or
“easy to finish.”&lt;&#x2F;p&gt;
&lt;p&gt;We may try to use off-the-shelf “maker” style embedded boards (Arduino or
Raspberry PI) instead of a SOM (System-on-module) designed for industrial use.&lt;&#x2F;p&gt;
&lt;p&gt;An interpreted language like Python is easy to use and definitely has its place
on your workstation, tooling, etc. But deploying, cross-compiling, upgrading,
and maintaining a Python stack on thousands of embedded Linux edge nodes is not
easy – Go is much better over the long haul.&lt;&#x2F;p&gt;
&lt;p&gt;Skipping documentation, CI&#x2F;CD, and other basic best practices is certainly
quicker to start, but long-term will slow you down.&lt;&#x2F;p&gt;
&lt;p&gt;We can skip tests when writing code (often faster up front), or we can take the
time to write tests as we implement features. Likewise, when we debug a problem,
we can just fix the problem, or we can reproduce the problem first with a test,
and then fix it to ensure it does not happen again.&lt;&#x2F;p&gt;
&lt;p&gt;Ignoring architecture up front is easier initially, but taking the time to think
through architectural issues like decoupling, life-cycle management, and
high-level performance, pays huge dividends long-term.&lt;&#x2F;p&gt;
&lt;p&gt;Outsourcing PCB design is easy to start, but owning the custom PCB designs in
your product (especially the integration points) gives you the flexibility to
easily fix, improve, and adapt.&lt;&#x2F;p&gt;
&lt;p&gt;When designing a PCB with constraints (such as high-speed or high-voltage), we
can manually route the board or invest time in creating DRC rules and
documentation that clearly details the board’s constraints. The first approach
might be quicker to get rev 1 out, but the latter makes it much easier to
maintain the design over time, onboard new people, etc.&lt;&#x2F;p&gt;
&lt;p&gt;When designing hardware, we can skip creating CAD libraries, assigning house
part numbers and instead hand-create BOMs. But long term it becomes very
difficult to manage even a small inventory parts in the lab, let alone
production. We have duplicates, things are lost, and mistakes are made.&lt;&#x2F;p&gt;
&lt;p&gt;We can do things like we’ve always done them (certainly easier to start), but
there are new technologies, tools, and workflows that can greatly improve our
productivity.&lt;&#x2F;p&gt;
&lt;p&gt;We certainly need to push hard to get to an MVP (minimal viable product), but
this should be done by cutting features, not the approach. However, most people
do exactly the opposite – they want all the features up front and rather cut
out the foundational investments in technology and process.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the thing – “easy to start” puts you on the path that accumulates
technical debt. As time goes on, things become more complex, fragile, and
difficult to manage. This approach does not scale.&lt;&#x2F;p&gt;
&lt;p&gt;“Easy to finish” puts you on the path to burn down technical debt. Over time you
look for patterns and ways to simplify things. You continuously improve all
aspects of the product. You select the best technologies at the time and adopt
new technologies when it makes sense. This approach scales.&lt;&#x2F;p&gt;
&lt;p&gt;Starting is easy, and finishing is hard. What are you optimizing for?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎧 Use a headset optimized for calls</title>
        <published>2024-12-06T00:00:00+00:00</published>
        <updated>2024-12-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0080-use-a-headset-optimized-for-calls/"/>
        <id>https://bec-systems.com/blog/0080-use-a-headset-optimized-for-calls/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0080-use-a-headset-optimized-for-calls/">&lt;p&gt;One thing most of us do routinely is voice calls or video conferencing. For this
to work, each party needs to have a microphone and a speaker.&lt;&#x2F;p&gt;
&lt;p&gt;The simplest setup is to use the microphone and speaker built into your phone,
laptop, or car. Sometimes this works pretty well.&lt;&#x2F;p&gt;
&lt;p&gt;But, often we are environments where this is background noise. Simple
microphones, especially those some distance from our mouths, cannot discern
background noise from our voice. AGC (automatic gain control) algorithms tend to
amplify any sound to capture your voice. The most baffling scenario is those
walking through a busy airport holding a phone in front of them in speakerphone
mode. Another disruptive problem is echo which sometimes occurs when using a
laptop mic&#x2F;speaker for video conferencing. Trying to talk when your voice is
being echoed back is nearly impossible.&lt;&#x2F;p&gt;
&lt;p&gt;Conversely, our ears are very good at differentiating what we want to hear from
local background noise. Our brain and ears are
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;why-are-our-ears-so-good-at-di-bJPNehLAQHCK.Z_0YtMDXQ&quot;&gt;very sophisticated instruments&lt;&#x2F;a&gt;
and include features such as using the time delay and intensity difference
between each ear to pinpoint a source, selective focus, frequency tuning,
adaptive processing, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Some headsets attempt to block out background noise to the microphone. The most
effective ones have a direction microphone located very close to your mouth (on
a boom), or a microphone array and DSP processing. Two examples I’ve used are
the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;gp&#x2F;product&#x2F;B01H2RBQUG&quot;&gt;Plantronics - Voyager 5200&lt;&#x2F;a&gt;
(Bluetooth) and the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Sennheiser-USB-C-508354-Professionals-Noise-Canceling&#x2F;dp&#x2F;B07P76F83J&quot;&gt;Sennheiser SC 160&lt;&#x2F;a&gt;
(USB).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;f&#x2F;f71222515c76770d7f814ea582966cb18b6b5cb0.jpeg&quot; alt=&quot;5200&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;uploads&#x2F;default&#x2F;original&#x2F;2X&#x2F;3&#x2F;38efc9618a0b2efe13a50a06fe01b3621bc28b3c.jpeg&quot; alt=&quot;SC 160&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are likely many other good options. I use the Plantronics with my phone
and the Sennheiser with my computer. Both are very effective at blocking out
background noise and I’m sure there are many other effective models.&lt;&#x2F;p&gt;
&lt;p&gt;The result is whomever I am communicating with can clearly hear what I am saying
without being distracted by background noise in my environment. This makes me
more effective.&lt;&#x2F;p&gt;
&lt;p&gt;Some headsets have noise noise cancellation for the speakers. This is very nice
for deep work when we are trying to focus and need to block out all sounds other
than perhaps some music. But they are of marginal use during a call because our
ears are already pretty good at focusing on one sound and during a call we have
the discussion to focus on.&lt;&#x2F;p&gt;
&lt;p&gt;Consider having separate headsets for deep work (noise-cancelling speakers) and
calls (noise-reducing microphones) as part of YOUR
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;tags&#x2F;personal&#x2F;&quot;&gt;Personal Platform&lt;&#x2F;a&gt;. This may seem
like a minor thing, but the small things add up. Using a good microphone is a
courtesy to those listening to us. It is a courtesy to the entire group on the
call that our background noise is not interrupting the call. It is professional.
It shows we care about others.&lt;&#x2F;p&gt;
&lt;p&gt;For more discussion and review, see
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;video-conferencing-notes&#x2F;117&quot;&gt;this thread&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚡ Are your processes proactive or reactive?</title>
        <published>2024-12-05T00:00:00+00:00</published>
        <updated>2024-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0079-are-your-processes-proactive-or-reactive/"/>
        <id>https://bec-systems.com/blog/0079-are-your-processes-proactive-or-reactive/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0079-are-your-processes-proactive-or-reactive/">&lt;p&gt;There are two ways to implement a process.&lt;&#x2F;p&gt;
&lt;p&gt;The traditional way is as a check to make sure people did everything right. This
could be required documentation that is written after a project is finished, a
separate QA department that runs tests after each release, or various
certifications like UL, FCC, CE, etc. There are certainly times when things like
this are necessary; however, writing documentation after the fact is never much
fun, and dealing with failure reports from the QA department is not all that
pleasant, and the FCC testing facility has been called “the house of pain.”
We’ll call this the “reactive” process approach.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative approach is the “proactive” process. Structure your documentation
efforts as part of the development process – as a way to help you think and as
a vehicle for collaboration. QA can also be implemented proactively as automated
tests that are run during development.&lt;&#x2F;p&gt;
&lt;p&gt;Proactive processes focus on well-designed tools that help the people doing the
work get it right vs. tools that help managers who oversee the work. Proactive
process tools are well-designed, fast, and a pleasure to use.&lt;&#x2F;p&gt;
&lt;p&gt;Think what could happen if UL focused on providing KiCad templates and DRC rule
sets for various high-voltage design scenarios that would help engineers do
their work instead of a bureaucratic morass that is very painful and expensive
to work through. The first approach encourages innovation, whereas the current
approach greatly hinders it.&lt;&#x2F;p&gt;
&lt;p&gt;Some reactive processes are necessary, but where is your focus? The more you can
shift your processes from reactive to proactive, the better off you’ll be. This
is what Platform Thinking is all about – building YOUR Proactive Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ Architecture vs. Optimization</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0078-architecture-vs-optimization/"/>
        <id>https://bec-systems.com/blog/0078-architecture-vs-optimization/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0078-architecture-vs-optimization/">&lt;p&gt;In 1968, “The Art of Computer Programming” by Donald Knuth was published with
the following quote:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This was in the age when computer resources were scarce.&lt;&#x2F;p&gt;
&lt;p&gt;We now live in the age of abundant computing resources, so it seems this
statement would be many times truer now.&lt;&#x2F;p&gt;
&lt;p&gt;Performance is important when we select technologies. For instance, Go or Rust
is significantly faster than Python and it is important to think about issues
like this up front. This is an architectural issue.&lt;&#x2F;p&gt;
&lt;p&gt;Deciding if we will use a message bus or not is an architectural issue.&lt;&#x2F;p&gt;
&lt;p&gt;However, if we receive data over a network, especially in distributed IoT
systems, the network is relatively slow. So it rarely pays to optimize how we
process data from remote systems until we reach a pretty large scale. This is an
optimization issue.&lt;&#x2F;p&gt;
&lt;p&gt;Creating an abstraction to reduce some duplicated code is an optimization.&lt;&#x2F;p&gt;
&lt;p&gt;With architecture, we need to think about it up front.&lt;&#x2F;p&gt;
&lt;p&gt;It rarely pays to optimize up front – that is best done later after some
learning.&lt;&#x2F;p&gt;
&lt;p&gt;And if we spend too much time optimizing, we never get to the learning. And if
we don’t learn from testing a working system, we’re likely optimizing the wrong
things.&lt;&#x2F;p&gt;
&lt;p&gt;Architecture vs Optimization – there is a difference.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creativity</title>
        <published>2024-11-25T00:00:00+00:00</published>
        <updated>2024-11-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0077-creativity/"/>
        <id>https://bec-systems.com/blog/0077-creativity/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0077-creativity/">&lt;blockquote&gt;
&lt;p&gt;“Creativity is just connecting things. When you ask creative people how they
did something, they feel a little guilty because they didn’t really do it,
they just saw something. It seemed obvious to them after a while. That’s
because they were able to connect experiences they’ve had and synthesize new
things“ – Steve Jobs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;(Thanks &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rodaparicio.kit.com&#x2F;posts&#x2F;seeing-things&quot;&gt;Rod&lt;&#x2F;a&gt; for this quote!)&lt;&#x2F;p&gt;
&lt;p&gt;As technology advances, being good at making connections (integration) is the
critical skill, as we can’t create it all ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;Part of YOUR Platform is building a high-quality toolkit of things to connect.&lt;&#x2F;p&gt;
&lt;p&gt;And knowing how, when, and where to connect.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔗 Coupling</title>
        <published>2024-11-22T00:00:00+00:00</published>
        <updated>2024-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0076-coupling/"/>
        <id>https://bec-systems.com/blog/0076-coupling/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0076-coupling/">&lt;p&gt;Good platforms emphasize loose coupling where one part of the system can change
without affecting another.&lt;&#x2F;p&gt;
&lt;p&gt;Not abstractions for the sake of abstraction.&lt;&#x2F;p&gt;
&lt;p&gt;But rather well-thought-out data structures and patterns.&lt;&#x2F;p&gt;
&lt;p&gt;A message bus like NATS is an excellent way to decouple a program. One part of
the system publishes information, and any other interested part can subscribe.&lt;&#x2F;p&gt;
&lt;p&gt;But for this to work, you must have simple and flexible data structures that
don’t change often. Otherwise, your system is now tightly coupled again.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;SimpleIot&#x2F;SimpleIot&quot;&gt;Simple data structures and messaging&lt;&#x2F;a&gt;
– a sane way to scale YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⏰ A platform stuck in time</title>
        <published>2024-11-21T00:00:00+00:00</published>
        <updated>2024-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0075-a-platform-stuck-in-time/"/>
        <id>https://bec-systems.com/blog/0075-a-platform-stuck-in-time/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0075-a-platform-stuck-in-time/">&lt;p&gt;Vintage is great in some contexts—I like old woodworking hand tools. Even in our
modern jobs, some vintage tools, like a pencil and paper, are still very useful.&lt;&#x2F;p&gt;
&lt;p&gt;But information technology moves forward, and we rarely benefit from using
decade-old phones, computers, programs, etc.&lt;&#x2F;p&gt;
&lt;p&gt;New information technology and tools are often simpler to use and more powerful.
Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;C -&amp;gt; Go&#x2F;Rust&#x2F;Zig&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Apache -&amp;gt; Caddy&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Vim -&amp;gt; Helix&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;x86 -&amp;gt; ARM -&amp;gt; RISCv (MPU)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;8051 -&amp;gt; PIC -&amp;gt; ARM -&amp;gt; RISCv (MCU)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;FreeRTOS -&amp;gt; Zephyr&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Kafka -&amp;gt; NATS&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rotating storage -&amp;gt; Solid state&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Information technology, and perhaps computer technology in general, is
different. The physical constraints are largely removed as we scale into GHz and
Terabytes, which opens the doors to human innovation and collaboration.&lt;&#x2F;p&gt;
&lt;p&gt;Innovation is largely a process of discovery, so you can’t predict where it will
go and what will happen. It is a result of development iterations that are now
happening at a massive scale and distributed across the globe.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, when you lock yourself into some version of technology in the name of
stability, cost savings, or whatever, you are also limiting the potential for
your product – for interesting things to happen that no one could have
predicted.&lt;&#x2F;p&gt;
&lt;p&gt;It takes humility to acknowledge this – that you can’t see the future, the best
you can do is prepare for it.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform is the vehicle that keeps your product development moving forward
with technology so that you are not stuck in time as you watch it pass you by.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🧪 What is a good abstraction?</title>
        <published>2024-11-20T00:00:00+00:00</published>
        <updated>2024-11-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0074-what-is-a-good-abstraction/"/>
        <id>https://bec-systems.com/blog/0074-what-is-a-good-abstraction/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0074-what-is-a-good-abstraction/">&lt;p&gt;When writing a program, abstraction is a powerful tool.&lt;&#x2F;p&gt;
&lt;p&gt;Every abstraction has a benefit and a cost. Hopefully, the value &amp;gt; cost.&lt;&#x2F;p&gt;
&lt;p&gt;There are good abstractions and bad abstractions.&lt;&#x2F;p&gt;
&lt;p&gt;Good abstractions break things down into simpler steps that others can
understand.&lt;&#x2F;p&gt;
&lt;p&gt;Bad abstractions may be brilliant but are nearly impossible for anyone but the
author to understand.&lt;&#x2F;p&gt;
&lt;p&gt;Who are you optimizing for? Yourself, or everyone else?&lt;&#x2F;p&gt;
&lt;p&gt;This often tells the difference between a good and bad abstraction.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚡ Improve development efficiency, reduce technical debt</title>
        <published>2024-11-18T00:00:00+00:00</published>
        <updated>2024-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0073-improve-development-efficiency-reduce-technical-debt/"/>
        <id>https://bec-systems.com/blog/0073-improve-development-efficiency-reduce-technical-debt/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0073-improve-development-efficiency-reduce-technical-debt/">&lt;p&gt;The term “platform” can mean a lot of things, but this is primarily what I’m
talking about in the context of product development:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Improve development efficiency, reduce technical debt&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;do more with what you have&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;iterate faster&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;make less mistakes&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;regularly update to new software versions&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;collaborate better&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;use better tools&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;automate where you can&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;reduce legacy (untested) code&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;deploy with confidence&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;react quickly to new customer needs or problems&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Of course, everyone wants these things and claims to be doing them. But in your
gut, you know if these things are getting better or worse.&lt;&#x2F;p&gt;
&lt;p&gt;And the only way I know to get better is to work on YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎯 Rituals and Culture</title>
        <published>2024-11-14T00:00:00+00:00</published>
        <updated>2024-11-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0072-rituals-and-culture/"/>
        <id>https://bec-systems.com/blog/0072-rituals-and-culture/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0072-rituals-and-culture/">&lt;p&gt;Recently,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0067-habits-a-critical-ingredient-in-your-personal-platform&#x2F;&quot;&gt;we discussed&lt;&#x2F;a&gt;
personal habits.&lt;&#x2F;p&gt;
&lt;p&gt;Organizations have habits too – we call them rituals and culture.&lt;&#x2F;p&gt;
&lt;p&gt;How does the organization react when things don’t go as planned?&lt;&#x2F;p&gt;
&lt;p&gt;How does the organization motivate and demotivate people?&lt;&#x2F;p&gt;
&lt;p&gt;How does the organization encourage openness and transparency?&lt;&#x2F;p&gt;
&lt;p&gt;A lot of this probably comes down to those at the top – the art of leadership.&lt;&#x2F;p&gt;
&lt;p&gt;Organizations are made of people, so the struggles we face personally we also
face organizationally.&lt;&#x2F;p&gt;
&lt;p&gt;We need some structure and tooling to help us do our job.&lt;&#x2F;p&gt;
&lt;p&gt;To ensure the boring parts are taken care of.&lt;&#x2F;p&gt;
&lt;p&gt;To catch errors we overlook.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms.&lt;&#x2F;p&gt;
&lt;p&gt;Does your organization celebrate platforms? If so, how?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 Two ways to scale</title>
        <published>2024-11-13T00:00:00+00:00</published>
        <updated>2024-11-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0071-two-ways-to-scale/"/>
        <id>https://bec-systems.com/blog/0071-two-ways-to-scale/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0071-two-ways-to-scale/">&lt;p&gt;Scaling is the goal of many businesses – grow revenue, serve more people, sell
more devices, grow the product line, etc.&lt;&#x2F;p&gt;
&lt;p&gt;There are two ways to scale:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Increase volume with a small number of direct customers. You might be making
an integrated circuit that is sold to a company making consumer devices, or
you might be making a consumer product that is sold through a few outlets
like Amazon and Walmart. Although you might have thousands of end customers,
you only have a few direct customers.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Increase the number of direct customers. Many of these customers may be low
volume, but the aggregate can be large, sometimes described as the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Long_tail&quot;&gt;long tail&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;(For this discussion, we’ll assume you already have a product or technology that
meets a real need).&lt;&#x2F;p&gt;
&lt;p&gt;With approach #1, you can brute force about anything. As long as the product is
something people want, you can dedicate application engineers to help your
customers make it happen. Sometimes the design&#x2F;development team interacts
directly with customers. This is expensive, and the reason many industrial
products are costly is that they rely on direct support.&lt;&#x2F;p&gt;
&lt;p&gt;However, this does not scale past a handful of customers. Direct application
engineering support is expensive. If you want to scale the number of customers,
you need to do something different.&lt;&#x2F;p&gt;
&lt;p&gt;Open-source projects are an interesting study in this regard. They address well
the needs of many users. How do they do this?&lt;&#x2F;p&gt;
&lt;p&gt;There are two primary aspects: A) Quality, and B) Community.&lt;&#x2F;p&gt;
&lt;p&gt;For any complex technology to scale without a lot of hand-holding, the quality
needs to be high. There has to be good documentation. The source code or design
needs to be readable. The architecture needs to be simple and solid so it can be
understood. You need consistency (data structures, code organization, etc.).
Testing needs to be automated and robust so there are not a lot of unexpected
problems.&lt;&#x2F;p&gt;
&lt;p&gt;The second thing that is needed is community. A community is the only way to
support a large number of users or customers of a complex technology. With
complex systems, the problems you run into are often things you have never seen
before. If all of these problems need to be solved from scratch with direct
one-on-one support, you will quickly become buried. Additionally, you’ll find
that experienced users are often better at solving user problems than technology
creators. If this support is done in a public place, you soon build up a
knowledge base that can be reused.&lt;&#x2F;p&gt;
&lt;p&gt;Quality and Community are the ways to scale the number of direct customers or
users, and OSS-style workflows and communities are the best way to accomplish
this.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to address the long tail, the days of NDAs with every customer are
past. The future is open. Not necessarily 100% open source, but certainly open
documentation and support. And “open” provides feedback that increases quality
– it all works together.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 How to get the little things done?</title>
        <published>2024-11-11T00:00:00+00:00</published>
        <updated>2024-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0070-how-to-get-the-little-things-done/"/>
        <id>https://bec-systems.com/blog/0070-how-to-get-the-little-things-done/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0070-how-to-get-the-little-things-done/">&lt;p&gt;Previously, we
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0067-habits-a-critical-ingredient-in-your-personal-platform&#x2F;&quot;&gt;discussed habits&lt;&#x2F;a&gt;.
Habits are the way we get the small, but important, things done.&lt;&#x2F;p&gt;
&lt;p&gt;Some people are naturally neat, organized, and focused – I’m not. Stuff tends
to pile up in my workspace and I don’t even notice it.&lt;&#x2F;p&gt;
&lt;p&gt;One thing I’ve been using some is the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pomodoro_Technique&quot;&gt;Pomodoro technique&lt;&#x2F;a&gt;. This is
a time management method where you use a timer to break down work into intervals
– typically 25 minutes in length separated by 5m breaks.&lt;&#x2F;p&gt;
&lt;p&gt;The primary goal of the Pomodoro technique is to increase focus, and that is a
worthy goal.&lt;&#x2F;p&gt;
&lt;p&gt;However, another benefit of this technique is to allocate time for the little
things, like organizing your workspace which is a good use of your 5m breaks.&lt;&#x2F;p&gt;
&lt;p&gt;These are the little things that clear space to do the big things – part of
YOUR Personal Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😊 How can you make your commercial source code customers happy?</title>
        <published>2024-11-08T00:00:00+00:00</published>
        <updated>2024-11-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0069-how-can-you-make-your-commercial-source-code-customers-happy/"/>
        <id>https://bec-systems.com/blog/0069-how-can-you-make-your-commercial-source-code-customers-happy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0069-how-can-you-make-your-commercial-source-code-customers-happy/">&lt;p&gt;When engaging with a community around an open-source project, Github is likely
the lowest friction option. It makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;But there are other scenarios – one is where you are delivering closed-source
commercial source code to customers.&lt;&#x2F;p&gt;
&lt;p&gt;Git makes sense for delivering any source code, no matter what the context –
closed, open, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Using zip files to deliver source is antiquated. Since Subversion (2000) and Git
(2005), there are now other options.&lt;&#x2F;p&gt;
&lt;p&gt;With Git, is easy to deliver updates, manage changes, tag releases, and track
what has happened.&lt;&#x2F;p&gt;
&lt;p&gt;Tools like Gitea&#x2F;Forgejo, that wrap Git, provide nice ways to interact around
the source code – issues, pull-requests, projects, etc. Issues and
pull-requests are much better ways to communicate about code than email or other
messaging methods. The communication is close to the code and preserved instead
of being disconnected, and eventually lost.&lt;&#x2F;p&gt;
&lt;p&gt;Gitea&#x2F;Forgejo also give us unlimited organizations and users that we can create
and manage. What this means is every customer can have their own organization.
This provides issolation between customers. Each now has their own space to
raise issues, discussion PRs, etc. You can mirror the source code they have
purchased to their own organizational space, and continue updating it as long as
they are a customer. If they decide to quit purchasing updates, you can leave
their Gitea organization and source code intact, but simply quit updating it.
This is ensures you do break build processes they already have in place and is a
measure of good will.&lt;&#x2F;p&gt;
&lt;p&gt;Why not deliver the source-code to the customer’s Github organization? You have
less control in Github. Simple things like users not being able to create an
account are now under your control. With Gitea, you have more control of the
repo visibility. It is less likely someone might accidentally make a repo public
in the future.&lt;&#x2F;p&gt;
&lt;p&gt;Would you like the velocity, stability, and collaboration that OSS projects
have? With tools like Gitea&#x2F;Forgejo, you can mirror these workflows into any
software development effort.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Platforms vs Architecture Astronautics</title>
        <published>2024-11-07T00:00:00+00:00</published>
        <updated>2024-11-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0068-platforms-vs-architecture-astronautics/"/>
        <id>https://bec-systems.com/blog/0068-platforms-vs-architecture-astronautics/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0068-platforms-vs-architecture-astronautics/">&lt;p&gt;The excellent &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;superstructmanifesto.com&#x2F;&quot;&gt;Superstruct Manifesto&lt;&#x2F;a&gt;
addresses the tendency for developers to want to “rewrite” things, wholesale
switch to new frameworks, jump on new tech, etc. vs. delivering real business
value.&lt;&#x2F;p&gt;
&lt;p&gt;Another description for these people is
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2001&#x2F;04&#x2F;21&#x2F;dont-let-architecture-astronauts-scare-you&#x2F;&quot;&gt;Architecture Astronauts&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms, at least the way I envision them, are the opposite of this.&lt;&#x2F;p&gt;
&lt;p&gt;They are incremental, not wholesale.&lt;&#x2F;p&gt;
&lt;p&gt;They are a part of our daily thinking, not some separate grandiose effort that
will solve all of our problems.&lt;&#x2F;p&gt;
&lt;p&gt;They are largely invisible.&lt;&#x2F;p&gt;
&lt;p&gt;They leverage what we already have and make it better.&lt;&#x2F;p&gt;
&lt;p&gt;They are the responsibility of everyone, from the bottom to the top, not some
elite team.&lt;&#x2F;p&gt;
&lt;p&gt;However, like personal habits, company platforms take discipline to implement
and are sometimes difficult to get established.&lt;&#x2F;p&gt;
&lt;p&gt;There are exceptions, but if platform work is exciting and interesting, this is
a warning flag – you may be venturing into architecture astronautics.
Generally, we need to block out time in our schedule to work on platforms as it
does not just happen because it is fun – kind of like brushing your teeth and
exercising.&lt;&#x2F;p&gt;
&lt;p&gt;But in the end, platforms make the difference whether you have a sustainable
business or just some talented individuals. And just like exercising, or
cleaning up our workspace, it is very satisfying afterward.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💪 Habits -- a critical ingredient in YOUR Personal Platform</title>
        <published>2024-11-06T00:00:00+00:00</published>
        <updated>2024-11-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0067-habits-a-critical-ingredient-in-your-personal-platform/"/>
        <id>https://bec-systems.com/blog/0067-habits-a-critical-ingredient-in-your-personal-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0067-habits-a-critical-ingredient-in-your-personal-platform/">&lt;p&gt;We &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0018-what-is-a-platform-v2&#x2F;&quot;&gt;defined&lt;&#x2F;a&gt; your
platform as the collection of technology, tools, and processes that enable you
to differentiate and consistently deliver your products and services.&lt;&#x2F;p&gt;
&lt;p&gt;At a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0020-three-levels-of-your-platform&#x2F;&quot;&gt;personal level&lt;&#x2F;a&gt;,
habits are critical – they enable us to do the boring&#x2F;hard stuff that makes us
effective.&lt;&#x2F;p&gt;
&lt;p&gt;Getting up early gives us undistracted time to think.&lt;&#x2F;p&gt;
&lt;p&gt;Regularly exercising helps us in so many ways.&lt;&#x2F;p&gt;
&lt;p&gt;Patterns and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;emergent-task-timer&#x2F;1421&quot;&gt;tools&lt;&#x2F;a&gt;
that help us plan and focus are sometimes necessary.&lt;&#x2F;p&gt;
&lt;p&gt;Bad habits (sleeping in, overeating, reading instead of working, etc.) are easy
to fall into.&lt;&#x2F;p&gt;
&lt;p&gt;Good habits are amazingly hard to establish, but worth it, and a big part of
YOUR Personal Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Advanced technology and small players</title>
        <published>2024-11-05T00:00:00+00:00</published>
        <updated>2024-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0066-advanced-technology-and-small-players/"/>
        <id>https://bec-systems.com/blog/0066-advanced-technology-and-small-players/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0066-advanced-technology-and-small-players/">&lt;p&gt;Integrated circuits (IC) vary widely in complexity from the small devices that
are easily documented and understood to complex beasts that would require a
stack of books and years to fully document.&lt;&#x2F;p&gt;
&lt;p&gt;If you are a high-volume manufacturer of consumer goods, you can easily get all
the attention and support you need from IC vendors. They will help you design
your product.&lt;&#x2F;p&gt;
&lt;p&gt;However, if you are a low volume manufacturer, it is nearly impossible to get
direct support for complex ICs. Support resources are limited and IC vendors
can’t help everyone in the world design their products.&lt;&#x2F;p&gt;
&lt;p&gt;So they allocate support engineers to a small number of higher-volume customers.&lt;&#x2F;p&gt;
&lt;p&gt;It does not matter how important you think you are, or how much money you have,
if you don’t have volume, it will be hard to get direct support from complex IC
vendors. Their margins are small and they make it up in volume.&lt;&#x2F;p&gt;
&lt;p&gt;However, there is a path forward for low-volume manufacturers.&lt;&#x2F;p&gt;
&lt;p&gt;You can buy system-on-modules (SOM) from vendors who do the hard parts of
integrating a processor, RAM, power supplies, and other complex ICs on a module.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, they provide open-source software for these modules. Open-source
has changed the game for software by providing everyone access to advanced
technology.&lt;&#x2F;p&gt;
&lt;p&gt;The third aspect of this is community. If a technology vendor has a vibrant
community around their products, then the community can support the low-volume
customers. This is the best and most sustainable model.&lt;&#x2F;p&gt;
&lt;p&gt;The difficult part in all this is discerning where the line is. What technology
is accessible to low-volume manufacturers and what is not?&lt;&#x2F;p&gt;
&lt;p&gt;A few red flags:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SOM or other module technologies that don’t have a clear support model for
industrial customers.&lt;&#x2F;li&gt;
&lt;li&gt;The technology is not open and requires NDAs to access documentation.&lt;&#x2F;li&gt;
&lt;li&gt;The documentation is inadequate and difficult to understand. The only way
you’ll figure it out is by the vendor helping you.&lt;&#x2F;li&gt;
&lt;li&gt;There is not a vibrant community around the products.&lt;&#x2F;li&gt;
&lt;li&gt;Supporting software is not open-source.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The accessibility of technology today has spurred tremendous innovation.
Open-source and community have changed the game enabling even small players to
use very advanced technology in their products. But you must understand your
limits. There is technology that is accessible to small players and technology
that is not.&lt;&#x2F;p&gt;
&lt;p&gt;IC vendors who put the pieces in place (openness, open-source, and community)
can benefit from the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Long_tail&quot;&gt;long tail&lt;&#x2F;a&gt; of
distribution, which increasingly is where innovation is happening.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What can kids teach us about platforms?</title>
        <published>2024-11-01T00:00:00+00:00</published>
        <updated>2024-11-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0066-what-can-school-students-teach-us-about-platforms/"/>
        <id>https://bec-systems.com/blog/0066-what-can-school-students-teach-us-about-platforms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0066-what-can-school-students-teach-us-about-platforms/">&lt;p&gt;When helping my children with math, one of the biggest struggles is to teach
them to break math problems into small steps. They are smart and think they can
do it in their head, and inevitably make mistakes because everything gets
muddled.&lt;&#x2F;p&gt;
&lt;p&gt;When you break a math problem into steps, it is easy – because each step is
easy.&lt;&#x2F;p&gt;
&lt;p&gt;And writing out the steps is easy. It’s not rocket science.&lt;&#x2F;p&gt;
&lt;p&gt;But what is not easy is the discipline to write out the problem step-by-step
instead of rushing to the answer.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform is the same way – it is breaking down problems into simple steps.&lt;&#x2F;p&gt;
&lt;p&gt;It’s not rocket science.&lt;&#x2F;p&gt;
&lt;p&gt;But it does take discipline to create a checklist, document a process, break
things down into smaller steps, automate some things, look for patterns, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Getting to simplicity is hard, but once you get there, everything is easier.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏛️ What are the pillars of a good platform?</title>
        <published>2024-10-31T00:00:00+00:00</published>
        <updated>2024-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0065-what-are-the-pillars-of-a-good-platform/"/>
        <id>https://bec-systems.com/blog/0065-what-are-the-pillars-of-a-good-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0065-what-are-the-pillars-of-a-good-platform/">&lt;p&gt;&lt;strong&gt;Simplicity&lt;&#x2F;strong&gt; - you can make changes when needed, and understand the system enough to do so.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Consistency&lt;&#x2F;strong&gt; - useful patterns are reused throughout the system where appropriate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Reliability&lt;&#x2F;strong&gt; - the design&#x2F;implementation is sound and there is enough testing that you don’t worry too much when deploying updates.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Velocity&lt;&#x2F;strong&gt; - iterations are fast and easy to deploy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🛣️ Kayaks and Platforms</title>
        <published>2024-10-30T00:00:00+00:00</published>
        <updated>2024-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0064-kayaks-and-platforms/"/>
        <id>https://bec-systems.com/blog/0064-kayaks-and-platforms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0064-kayaks-and-platforms/">&lt;p&gt;Recently we purchased a few used kayaks that had been built 20 years ago from
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;pygmyboats.net&#x2F;&quot;&gt;Pygmy Boats kits&lt;&#x2F;a&gt;. (Unfortunately, Pygmy is not longer
supplying kits, but similar kits can be purchased from
&lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0064-kayaks-and-platforms&#x2F;(https:&#x2F;&#x2F;clcboats.com&#x2F;index.php)&quot;&gt;Chesapeake Light Craft&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;kayaks.jpg&quot; alt=&quot;kayaks&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We had the pleasure of visiting with the former owner (Mike) for an hour or so
and he generously shared his knowledge about the boats, and kayaking in general.&lt;&#x2F;p&gt;
&lt;p&gt;The more I listened to Mike, the more I realized these boats were his platform
for getting on the water.&lt;&#x2F;p&gt;
&lt;p&gt;Building a boat like this from a kit is a lot of work, but in the end you have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a nice boat – performs as good as boats 4x the cost&lt;&#x2F;li&gt;
&lt;li&gt;one that is customized to exactly what you need (features, rigging, seat,
bracing, etc).&lt;&#x2F;li&gt;
&lt;li&gt;can be easily modified in the future&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, you have the know-how and tools to repair and maintain it.&lt;&#x2F;p&gt;
&lt;p&gt;If the hull is damaged, you can get your extra plywood, fiberglass cloth, and
epoxy, and fix it.&lt;&#x2F;p&gt;
&lt;p&gt;If you don’t like the rigging, you can fasten new points and fill the old holes.&lt;&#x2F;p&gt;
&lt;p&gt;If you don’t like the seat, and can hand-carve a new one out of a block of foam.&lt;&#x2F;p&gt;
&lt;p&gt;If the boat is scratched up, a little sandpaper and varnish will have it looking
like new.&lt;&#x2F;p&gt;
&lt;p&gt;It’s not for everyone, but for those who want to own their kayak platform, a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stitch_and_glue&quot;&gt;stitch and glue&lt;&#x2F;a&gt; boat is nice
option.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💻 What is the purpose of technology?</title>
        <published>2024-10-29T00:00:00+00:00</published>
        <updated>2024-10-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0063-what-is-the-purpose-of-technology/"/>
        <id>https://bec-systems.com/blog/0063-what-is-the-purpose-of-technology/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0063-what-is-the-purpose-of-technology/">&lt;p&gt;To do more with less effort.&lt;&#x2F;p&gt;
&lt;p&gt;To simplify our tasks.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes this backfires and technology ends up giving us more to do and
complicates our lives.&lt;&#x2F;p&gt;
&lt;p&gt;It becomes a monster and we are consumed feeding it.&lt;&#x2F;p&gt;
&lt;p&gt;Thus, the selection and implementation of technology is critical.&lt;&#x2F;p&gt;
&lt;p&gt;How do you objectively measure this?&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps we need a term “technical efficiency”&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;technical efficiency = time saved&#x2F;time feeding&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hard to measure, but important to reflect on.&lt;&#x2F;p&gt;
&lt;p&gt;A number greater than 1 is good, less than 1 is bad. Ideally, the number should
be much greater than one and also increasing.&lt;&#x2F;p&gt;
&lt;p&gt;Like with so many things, the key metric is not where we are now, but where we
are heading.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✨ The easiest path to reliability ...</title>
        <published>2024-10-25T00:00:00+00:00</published>
        <updated>2024-10-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0062-the-easiest-path-to-reliability/"/>
        <id>https://bec-systems.com/blog/0062-the-easiest-path-to-reliability/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0062-the-easiest-path-to-reliability/">&lt;p&gt;… is simplicity.&lt;&#x2F;p&gt;
&lt;p&gt;Not that we dumb things down and avoid new technology.&lt;&#x2F;p&gt;
&lt;p&gt;That is false simplicity.&lt;&#x2F;p&gt;
&lt;p&gt;As we
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0061-where-do-reliability-stability-problems-typically-come-from&#x2F;&quot;&gt;discussed previously&lt;&#x2F;a&gt;,
the problem is most often not with the underlying technology, but rather the
stuff we do.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, if we can simplify what we do, it will get better.&lt;&#x2F;p&gt;
&lt;p&gt;This is a fundamental purpose of YOUR Platform – to simplify what you do. To
make it more repeatable, deployable, reliable, and stable.&lt;&#x2F;p&gt;
&lt;p&gt;Technology and tools can help, but in the end what you do and how you do it is
your responsibility. You can’t buy a solution for this, nor can AI do it all for
you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 Where do reliability&#x2F;stability problems typically come from?</title>
        <published>2024-10-24T00:00:00+00:00</published>
        <updated>2024-10-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0061-where-do-reliability-stability-problems-typically-come-from/"/>
        <id>https://bec-systems.com/blog/0061-where-do-reliability-stability-problems-typically-come-from/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0061-where-do-reliability-stability-problems-typically-come-from/">&lt;p&gt;99% of the time, system bugs&#x2F;problems come from the stuff you do.&lt;&#x2F;p&gt;
&lt;p&gt;The code you wrote.&lt;&#x2F;p&gt;
&lt;p&gt;The hardware you designed.&lt;&#x2F;p&gt;
&lt;p&gt;The system you configured.&lt;&#x2F;p&gt;
&lt;p&gt;The custom PRC system you created.&lt;&#x2F;p&gt;
&lt;p&gt;Rarely are we affected by stability problems in the Linux kernel, the Zephyr
RTOS, an OSS library, or a bug in a chip.&lt;&#x2F;p&gt;
&lt;p&gt;Why? Because these components have many more users and developers than the
in-house pieces we develop.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.laws-of-software.com&#x2F;laws&#x2F;linus&#x2F;&quot;&gt;“Given enough eyeballs, all bugs are shallow.”&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Why are we so hesitant to update the open source system software in our product,
but deploy new application updates that one developer created without a thought?&lt;&#x2F;p&gt;
&lt;p&gt;And ironically, the best way to avoid the rare problem in OSS components is to
keep up-to-date.&lt;&#x2F;p&gt;
&lt;p&gt;We should be most suspect of the parts of the systems with few developers and
users.&lt;&#x2F;p&gt;
&lt;p&gt;This is why YOUR Platform is so important – because you reuse it, more
developers work on it, and more users use it.&lt;&#x2F;p&gt;
&lt;p&gt;And by extension why it is so beneficial to open source parts of what you do.
Even if you get only a few more users, it will get a lot better, making your
products better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔝 Support from the top</title>
        <published>2024-10-23T00:00:00+00:00</published>
        <updated>2024-10-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0060-support-from-the-top/"/>
        <id>https://bec-systems.com/blog/0060-support-from-the-top/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0060-support-from-the-top/">&lt;p&gt;In a recent &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;035&#x2F;&quot;&gt;discussion with Matthew Rassi&lt;&#x2F;a&gt; about Lean,
I asked Matthew if he has ever witnessed Lean being successful in organizations
where there is not support at the top. He answered with a resounding no.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise, I’ve never observed “Platform Thinking” being successful company-wide
without support from management.&lt;&#x2F;p&gt;
&lt;p&gt;If Platform thinking does not start at the top, it is a hard go.&lt;&#x2F;p&gt;
&lt;p&gt;These are cultural issues, and perhaps the most important influence those in
leadership positions have is culture.&lt;&#x2F;p&gt;
&lt;p&gt;However, you can still apply platform thinking at the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0020-three-levels-of-your-platform&#x2F;&quot;&gt;personal or sometimes team level&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;platform-levels.png&quot; alt=&quot;levels&quot; style=&quot;zoom: 67%;&quot; &#x2F;&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎯 Doing more with less, rather than less with more</title>
        <published>2024-10-22T00:00:00+00:00</published>
        <updated>2024-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0059-doing-more-with-less-rather-than-less-with-more/"/>
        <id>https://bec-systems.com/blog/0059-doing-more-with-less-rather-than-less-with-more/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0059-doing-more-with-less-rather-than-less-with-more/">&lt;p&gt;Building your platform does not mean you need to invent a bunch of stuff from scratch, or purchase expensive tools.&lt;&#x2F;p&gt;
&lt;p&gt;Rather, it is making better use of what you already have.&lt;&#x2F;p&gt;
&lt;p&gt;Automating your current workflows and deployment.&lt;&#x2F;p&gt;
&lt;p&gt;Reusing the designs and IP you already have.&lt;&#x2F;p&gt;
&lt;p&gt;Increasing the rate of iterations.&lt;&#x2F;p&gt;
&lt;p&gt;Automated testing so that you can deploy with confidence.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms are not rocket science, and you don’t need fancy tools to get started.&lt;&#x2F;p&gt;
&lt;p&gt;A checklist can do wonders.&lt;&#x2F;p&gt;
&lt;p&gt;A few shell scripts and a cron job can get you a long ways.&lt;&#x2F;p&gt;
&lt;p&gt;Automation can be written in the languages you are already using on the project.&lt;&#x2F;p&gt;
&lt;p&gt;Building testing and diagnostics into your products rather than needing expensive, external fixtures.&lt;&#x2F;p&gt;
&lt;p&gt;Leverage the CI features built into tools like Github and Gitea.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms are the boring work that clear the path and you give you time and space to do the interesting work that adds value to your products.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🆘 How to ask for help</title>
        <published>2024-10-21T00:00:00+00:00</published>
        <updated>2024-10-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0058-how-to-ask-for-help/"/>
        <id>https://bec-systems.com/blog/0058-how-to-ask-for-help/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0058-how-to-ask-for-help/">&lt;p&gt;Modern systems are too complex for any of us to know everything about them.&lt;&#x2F;p&gt;
&lt;p&gt;Many of the problems we encounter we have never seen before.&lt;&#x2F;p&gt;
&lt;p&gt;Communities built around various technologies are what fill this gap.&lt;&#x2F;p&gt;
&lt;p&gt;So the superpower in this age is first having the humility to ask for help, and
then knowing who and how to ask for help.&lt;&#x2F;p&gt;
&lt;p&gt;Before asking anything, do a reasonable amount of work.&lt;&#x2F;p&gt;
&lt;p&gt;Someone once told me he puts thirty minutes into a problem before asking a
co-worker for help, which seems like a good baseline. Any less than that you are
likely needlessly interrupting and distracting someone from their work. Any more
than that you may be spinning your wheels needlessly. The nature of the problem
may justify more at times.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes our questions are met with silence.&lt;&#x2F;p&gt;
&lt;p&gt;Don’t just remind people that you need help.&lt;&#x2F;p&gt;
&lt;p&gt;Do more work, and bring more information, and then ask again.&lt;&#x2F;p&gt;
&lt;p&gt;If you ask more questions, always bring more information.&lt;&#x2F;p&gt;
&lt;p&gt;Help people help you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 How to keep a product maintainable?</title>
        <published>2024-10-18T00:00:00+00:00</published>
        <updated>2024-10-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0057-how-to-keep-a-product-maintainable/"/>
        <id>https://bec-systems.com/blog/0057-how-to-keep-a-product-maintainable/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0057-how-to-keep-a-product-maintainable/">&lt;p&gt;How do you know if you have the ability to maintain your product?&lt;&#x2F;p&gt;
&lt;p&gt;With complex systems, having all the design files and source code does not
always mean a lot.&lt;&#x2F;p&gt;
&lt;p&gt;Do you know how to build the source code?&lt;&#x2F;p&gt;
&lt;p&gt;Do you know why the hardware is designed the way it is?&lt;&#x2F;p&gt;
&lt;p&gt;Do you know how to test and verify changes?&lt;&#x2F;p&gt;
&lt;p&gt;Do you regularly use these tools?&lt;&#x2F;p&gt;
&lt;p&gt;The only way to know for sure if you can efficiently make a change to your
product is to practice doing so.&lt;&#x2F;p&gt;
&lt;p&gt;If you don’t, things soon ossify to the point where the cost and risk of any
change are prohibitive.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤝 What happens when someone else tries to use your work?</title>
        <published>2024-10-17T00:00:00+00:00</published>
        <updated>2024-10-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0056-what-happens-when-someone-else-tries-to-use-your-work/"/>
        <id>https://bec-systems.com/blog/0056-what-happens-when-someone-else-tries-to-use-your-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0056-what-happens-when-someone-else-tries-to-use-your-work/">&lt;p&gt;It does not build on machine X …&lt;&#x2F;p&gt;
&lt;p&gt;It does not work in scenario Y …&lt;&#x2F;p&gt;
&lt;p&gt;It is hard to understand by developer Z …&lt;&#x2F;p&gt;
&lt;p&gt;As developers, we naturally avoid the rough edges of whatever we are working on – it hurts.&lt;&#x2F;p&gt;
&lt;p&gt;When other developers try to build&#x2F;run our stuff, it is amazing what they find.&lt;&#x2F;p&gt;
&lt;p&gt;The more people you have building and running your stuff, the better it will be.&lt;&#x2F;p&gt;
&lt;p&gt;Even two people vs. one makes a huge difference.&lt;&#x2F;p&gt;
&lt;p&gt;The platform approach says anyone should be able to easily check out, build, and run any code on any machine.&lt;&#x2F;p&gt;
&lt;p&gt;We’ve run this experiment with OSS projects for a long time – it works.&lt;&#x2F;p&gt;
&lt;p&gt;Encourage others to build and run your code – it will make YOUR Platform better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📌 Where do you put stuff?</title>
        <published>2024-10-16T00:00:00+00:00</published>
        <updated>2024-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0055-where-do-you-put-stuff/"/>
        <id>https://bec-systems.com/blog/0055-where-do-you-put-stuff/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0055-where-do-you-put-stuff/">&lt;p&gt;There are a lot of ways to organize product development information.&lt;&#x2F;p&gt;
&lt;p&gt;You could do something like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;productA&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;firmware&lt;&#x2F;li&gt;
&lt;li&gt;hardware&lt;&#x2F;li&gt;
&lt;li&gt;yocto-build&lt;&#x2F;li&gt;
&lt;li&gt;docs&lt;&#x2F;li&gt;
&lt;li&gt;manufacturing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;productB&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;firmware&lt;&#x2F;li&gt;
&lt;li&gt;hardware&lt;&#x2F;li&gt;
&lt;li&gt;yocto-build&lt;&#x2F;li&gt;
&lt;li&gt;docs&lt;&#x2F;li&gt;
&lt;li&gt;manufacturing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above is nice in that it keeps all the stuff for each product together, but
discourages re-use between projects.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to build a platform, then it may make more sense to do something
like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Firmware&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Boards
&lt;ul&gt;
&lt;li&gt;productA&lt;&#x2F;li&gt;
&lt;li&gt;productB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Apps&lt;&#x2F;li&gt;
&lt;li&gt;Common&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Hardware&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Part Libs&lt;&#x2F;li&gt;
&lt;li&gt;productA&lt;&#x2F;li&gt;
&lt;li&gt;productB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Yocto&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Manufacturing&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Common testing framework&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Product&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;productA&lt;&#x2F;li&gt;
&lt;li&gt;productB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Doc&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;(general technology information)&lt;&#x2F;li&gt;
&lt;li&gt;(general processes, etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each type of code&#x2F;design files live in a common location if possible. The
&lt;code&gt;Product&lt;&#x2F;code&gt; location is only for information that is truly unique to a specific
product (documentation, top-level BOMs, etc) that does not fit anywhere else. In
many cases, each of the top level categories are a separate repo. The &lt;code&gt;Product&lt;&#x2F;code&gt;
repo may pull the other repos in as submodules, so you can version everything
together.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to build a platform, it helps to be intentional about this. Reuse
and cross-product learning won’t just happen.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌱 When edge nodes grow up</title>
        <published>2024-10-15T00:00:00+00:00</published>
        <updated>2024-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0054-when-edge-nodes-grow-up/"/>
        <id>https://bec-systems.com/blog/0054-when-edge-nodes-grow-up/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0054-when-edge-nodes-grow-up/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0053-how-do-you-partition-systems&#x2F;&quot;&gt;Yesterday&lt;&#x2F;a&gt; we
discussed how to partition functionality in hierarchical distributed systems.&lt;&#x2F;p&gt;
&lt;p&gt;In the past, it was difficult to do much at the edge nodes because they could
not do much.&lt;&#x2F;p&gt;
&lt;p&gt;Resources were limited.&lt;&#x2F;p&gt;
&lt;p&gt;It was difficult to update software in them without being on-site and connecting
a PC-based programmer, or before that replacing an OTP (one-time-programmable)
chip.&lt;&#x2F;p&gt;
&lt;p&gt;But today things are different.&lt;&#x2F;p&gt;
&lt;p&gt;A powerful 32-bit MCU is as now as cheap as your father’s 8-bit PIC and your
grandfather’s 8051.&lt;&#x2F;p&gt;
&lt;p&gt;It has plenty of memory for network&#x2F;communication stacks, and in-system update
routines.&lt;&#x2F;p&gt;
&lt;p&gt;We now have powerful operating systems like Zephyr that we can run on these edge
nodes.&lt;&#x2F;p&gt;
&lt;p&gt;If we continue our analogy to human systems, when a person is young or
inexperienced, we don’t push a lot of responsibility on them.&lt;&#x2F;p&gt;
&lt;p&gt;However, when they grow up, we want them to do more, make decisions, and look
around and do what needs done.&lt;&#x2F;p&gt;
&lt;p&gt;Modern MCU’s are capable of doing a lot including
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;033&#x2F;&quot;&gt;running AI algorithms&lt;&#x2F;a&gt; – maybe it is time our edge
nodes grow up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔠 How do you partition systems?</title>
        <published>2024-10-14T00:00:00+00:00</published>
        <updated>2024-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0053-how-do-you-partition-systems/"/>
        <id>https://bec-systems.com/blog/0053-how-do-you-partition-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0053-how-do-you-partition-systems/">&lt;p&gt;In modern networked systems, there is often the debate how to partition the
system.&lt;&#x2F;p&gt;
&lt;p&gt;Below is one example where you have three levels: cloud, gateway, and IO
(input&#x2F;output) nodes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;iot-architecture.png&quot; alt=&quot;iot system&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;All of these devices have a processor and can run software and do stuff.&lt;&#x2F;p&gt;
&lt;p&gt;So where do you do stuff? There are two basic philosophies:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Push as much of the processing upstream to the cloud (where you have
“infinite” resources) and never update downstream devices.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Do as much at the Gateway and IO nodes as possible, make decisions when
possible with local data, and only push processed data and events upstream.
This requires routinely updating the downstream devices as needs change and
better algorithms are developed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Initially, approach #1 seems simpler and may be appropriate in some cases.&lt;&#x2F;p&gt;
&lt;p&gt;You can centralize logic and decisions as much as possible.&lt;&#x2F;p&gt;
&lt;p&gt;It is easy to update the system – you only have to update one central piece.&lt;&#x2F;p&gt;
&lt;p&gt;Until you need to scale, or there is a network disruption …&lt;&#x2F;p&gt;
&lt;p&gt;And have 50 IO nodes per site that are sending frequent unprocessed data all the
way to the cloud, and decisions are coming back down, even when nothing is
changing.&lt;&#x2F;p&gt;
&lt;p&gt;And then you eventually have 1000 sites.&lt;&#x2F;p&gt;
&lt;p&gt;And then there is a cloud outage and the system is in limbo until the cloud
issue is fixed. All data during the outage is lost.&lt;&#x2F;p&gt;
&lt;p&gt;And someone damages the CAN bus cable and an actuator is left in the ON state
and a tank overflows because no one is making decisions.&lt;&#x2F;p&gt;
&lt;p&gt;And you are storing Gigabytes of unprocessed historical data that you never use.&lt;&#x2F;p&gt;
&lt;p&gt;Distributed systems are hard, but in the end they scale and are more resilient,
especially when you are forced to be distributed by device locations. Within
reason, the more processing you push to the edge, the better. “Distributed” in
these systems is not an architectural choice, but is forced on us by topology.
Why not leverage this since we need to deal with it anyway.&lt;&#x2F;p&gt;
&lt;p&gt;We can compare this to human systems. How well do autocratic, centralized
organizations work? Where someone at the top makes all the decisions and the
rest are minions?&lt;&#x2F;p&gt;
&lt;p&gt;They may work OK at a small scale, but even that is questionable.&lt;&#x2F;p&gt;
&lt;p&gt;A student of history soon observes that successful organizations push
responsibility down. People at the top provide oversight but are only involved
in local decision-making when coordination is required. Trusted people feed
necessary information up as required.&lt;&#x2F;p&gt;
&lt;p&gt;Is it any different with hierarchical, distributed digital systems?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏷️ How do you consistently name things?</title>
        <published>2024-10-10T00:00:00+00:00</published>
        <updated>2024-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0052-how-do-you-consistently-name-things/"/>
        <id>https://bec-systems.com/blog/0052-how-do-you-consistently-name-things/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0052-how-do-you-consistently-name-things/">&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things. – Phil Karlton&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Plenty of opinions abound on style, naming conventions, formatting, etc.&lt;&#x2F;p&gt;
&lt;p&gt;But there is one principle I try to follow when naming things – go from general to specific. Example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UserEmailAddress&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For functions, you may have a module that has multiple operations. In this case, the operation is a specific operation of a more general module.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;atmtcp_v_dev_open()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;atmtcp_v_dev_init()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;atmtcp_v_dev_close()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Even though &lt;code&gt;open_atmtcp_v_dev()&lt;&#x2F;code&gt; reads better as an English sentence. Programs can be thought as both prose and data, and sometimes there are advantages to considering function and variable names as data.&lt;&#x2F;p&gt;
&lt;p&gt;General-&amp;gt;specific naturally organizes things. It is easy to browse variables in an editor that may list all the variables in a module. Searching&#x2F;refactoring is also easier.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes when dealing with two unrelated types of information, it is not obvious which is more specific. In the below example, &lt;code&gt;VINST&#x2F;VPEAK&lt;&#x2F;code&gt; are measurements (type), and &lt;code&gt;AX&#x2F;AY&#x2F;...&lt;&#x2F;code&gt; are channels (instance). Which should go first?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VINST_AX&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;VINST_AY&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;VINST_AZ&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;VPEAK_AX&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Generally I prefer to put the “type” first, and then the “instance” – especially if there are multiple instances.  But this could probably go either way.&lt;&#x2F;p&gt;
&lt;p&gt;Another way to think about this is &lt;code&gt;VINST&lt;&#x2F;code&gt; may be a map&#x2F;dictionary&#x2F;hash-table property of an object, and &lt;code&gt;AX&#x2F;AY&#x2F;AZ&lt;&#x2F;code&gt; may be keys into this map.&lt;&#x2F;p&gt;
&lt;p&gt;Use nouns for variables and verbs for functions.&lt;&#x2F;p&gt;
&lt;p&gt;Does this make sense? How do you name things?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 How can we be more consistent?</title>
        <published>2024-10-09T00:00:00+00:00</published>
        <updated>2024-10-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0051-how-can-we-be-more-consistent/"/>
        <id>https://bec-systems.com/blog/0051-how-can-we-be-more-consistent/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0051-how-can-we-be-more-consistent/">&lt;p&gt;What does not work very well is long standards and endless code reviews where we shame people into compliance. There are better ways.&lt;&#x2F;p&gt;
&lt;p&gt;We now have tools that can proactively format our code. We have linting tools that check things. Use them. Even if no one else reads our code, they help us.&lt;&#x2F;p&gt;
&lt;p&gt;Write tests. Perhaps their greatest value is that they give us a new perspective on our work, which leads to consistency.&lt;&#x2F;p&gt;
&lt;p&gt;We can have CI hooks that check for various things – check out the Zephyr project if you want a good example of this.&lt;&#x2F;p&gt;
&lt;p&gt;Being nudged by a CI tool to be consistent is a much better experience than being pulled over by the consistency police.&lt;&#x2F;p&gt;
&lt;p&gt;Does YOUR Platform have tooling that encourages consistency?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 Does consistency matter?</title>
        <published>2024-10-08T00:00:00+00:00</published>
        <updated>2024-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0050-does-consistency-matter/"/>
        <id>https://bec-systems.com/blog/0050-does-consistency-matter/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0050-does-consistency-matter/">&lt;p&gt;If you have a single developer on a single project, then perhaps consistency does not matter too much.&lt;&#x2F;p&gt;
&lt;p&gt;However, if you want to scale, either products or developers, then consistency matters.&lt;&#x2F;p&gt;
&lt;p&gt;Why?&lt;&#x2F;p&gt;
&lt;p&gt;So that code does not get drastically reformatted every time someone makes a change, making Git diffs impossible to review.&lt;&#x2F;p&gt;
&lt;p&gt;So that any developer can easily understand and make changes in any part of the codebase.&lt;&#x2F;p&gt;
&lt;p&gt;So that new products can leverage previous efforts.&lt;&#x2F;p&gt;
&lt;p&gt;So that new developers can be more easily on-boarded.&lt;&#x2F;p&gt;
&lt;p&gt;So that we can see patterns and simplify systems.&lt;&#x2F;p&gt;
&lt;p&gt;So that our systems are tested.&lt;&#x2F;p&gt;
&lt;p&gt;So that documentation can be easily found.&lt;&#x2F;p&gt;
&lt;p&gt;Linux Torvalds is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.theregister.com&#x2F;2024&#x2F;10&#x2F;08&#x2F;torvalds_grammar_complaint&#x2F;&quot;&gt;being lambasted&lt;&#x2F;a&gt; for encouraging some consistency in Git commits.&lt;&#x2F;p&gt;
&lt;p&gt;But if you read his &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lkml.iu.edu&#x2F;hypermail&#x2F;linux&#x2F;kernel&#x2F;2410.0&#x2F;07495.html&quot;&gt;actual email&lt;&#x2F;a&gt;, the request seems quite reasonable.&lt;&#x2F;p&gt;
&lt;p&gt;The Linux kernel has a well-defined &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.kernel.org&#x2F;doc&#x2F;html&#x2F;v6.1&#x2F;process&#x2F;coding-style.html&quot;&gt;coding style&lt;&#x2F;a&gt; that all contributors are expected to follow.&lt;&#x2F;p&gt;
&lt;p&gt;Have we considered the impact this emphasis on consistency has had on the Linux Kernel’s success?&lt;&#x2F;p&gt;
&lt;p&gt;The irony of all this is that consistency is usually done in the name of the “team” or “reuse”. But if we reflect a bit, we are mostly just helping ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;We can read and understand our own code in 6 months.&lt;&#x2F;p&gt;
&lt;p&gt;We can find stuff.&lt;&#x2F;p&gt;
&lt;p&gt;We can more easily make changes and improvements.&lt;&#x2F;p&gt;
&lt;p&gt;We have tools helping us.&lt;&#x2F;p&gt;
&lt;p&gt;A little bit of consistency goes a long way in building YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎲 Isn&#x27;t it risky to update your dependencies?</title>
        <published>2024-10-07T00:00:00+00:00</published>
        <updated>2024-10-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0049-isnt-it-risky-to-update-your-dependencies/"/>
        <id>https://bec-systems.com/blog/0049-isnt-it-risky-to-update-your-dependencies/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0049-isnt-it-risky-to-update-your-dependencies/">&lt;p&gt;This is a common objection I hear when building industrial systems: “We want to
lock things down to a super stable&#x2F;tested LTS (Long Term Support) release and
then stay on that release for a long time – it’s risky to update dependencies.”&lt;&#x2F;p&gt;
&lt;p&gt;Is it?&lt;&#x2F;p&gt;
&lt;p&gt;How often do you update your browser?&lt;&#x2F;p&gt;
&lt;p&gt;Your phone?&lt;&#x2F;p&gt;
&lt;p&gt;How often does Windows or MacOS force you to update your computer OS?&lt;&#x2F;p&gt;
&lt;p&gt;Do you worry every time it updates?&lt;&#x2F;p&gt;
&lt;p&gt;I’ve run Arch Linux for years and update routinely without worrying.&lt;&#x2F;p&gt;
&lt;p&gt;I update to new versions of Gitea every time they come without a concern.&lt;&#x2F;p&gt;
&lt;p&gt;I routinely update to the latest HEAD of Zephyr on projects during development
and have rarely had a problem.&lt;&#x2F;p&gt;
&lt;p&gt;The same with about every software component I use.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, there are safety-critical control systems that have stringent testing
requirements, but we’re talking about complex connected systems that are mainly
concerned with moving data around.&lt;&#x2F;p&gt;
&lt;p&gt;Where security is a concern.&lt;&#x2F;p&gt;
&lt;p&gt;With rare exceptions, modern OSS projects get more stable with each release, and
to a lesser extent with each Git commit.&lt;&#x2F;p&gt;
&lt;p&gt;They have defied the laws of entropy.&lt;&#x2F;p&gt;
&lt;p&gt;How? With OSS workflows, testing, continuous integration (CI), more real-world
usage, more user feedback and contributions, etc.&lt;&#x2F;p&gt;
&lt;p&gt;With good CI, changes don’t get merged to main until they are tested pretty
well.&lt;&#x2F;p&gt;
&lt;p&gt;Transparency, community, and OSS workflows are powerful – really the only
practical way to build complex technology.&lt;&#x2F;p&gt;
&lt;p&gt;The next time you seek the cozy cocoon of an LTS release for a dependency in
YOUR Platform, think about what you might be giving up … features,
improvements, community connection, and likely also stability.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏗️ Platforms are for building systems</title>
        <published>2024-10-04T00:00:00+00:00</published>
        <updated>2024-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0048-platforms-are-for-building-systems/"/>
        <id>https://bec-systems.com/blog/0048-platforms-are-for-building-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0048-platforms-are-for-building-systems/">&lt;p&gt;If you are building a one-off, non-connected device, you can get by without a
platform.&lt;&#x2F;p&gt;
&lt;p&gt;This is why so many design-shops don’t get platforms – they are designing
something then moving on to the next project.&lt;&#x2F;p&gt;
&lt;p&gt;But if you are building a connected system, you have a much bigger problem to
solve.&lt;&#x2F;p&gt;
&lt;p&gt;You now have a distributed system, and distributed systems are hard.&lt;&#x2F;p&gt;
&lt;p&gt;You are now living on the Internet with all its associated security concerns.&lt;&#x2F;p&gt;
&lt;p&gt;You have a system that has the potential to do so much more than it is doing
now.&lt;&#x2F;p&gt;
&lt;p&gt;You have a system that has almost unlimited potential to be expanded.&lt;&#x2F;p&gt;
&lt;p&gt;You (potentially) have a platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💸 The cost of updating dependencies, or not</title>
        <published>2024-10-02T00:00:00+00:00</published>
        <updated>2024-10-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0047-updating-dependencies/"/>
        <id>https://bec-systems.com/blog/0047-updating-dependencies/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0047-updating-dependencies/">&lt;p&gt;As developers, we are often lazy when it comes to updating dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;A short-term productivity hack is to not update them.&lt;&#x2F;p&gt;
&lt;p&gt;Leave our Yocto build at an old version.&lt;&#x2F;p&gt;
&lt;p&gt;Never touch &lt;code&gt;go.mod&lt;&#x2F;code&gt; or &lt;code&gt;package.json&lt;&#x2F;code&gt; – everything is working and I can keep
focusing on coding features.&lt;&#x2F;p&gt;
&lt;p&gt;Don’t update our tools – we don’t have time.&lt;&#x2F;p&gt;
&lt;p&gt;… until things break, there is a security problem in a dependency, or we need
a feature in a new version of something, etc.&lt;&#x2F;p&gt;
&lt;p&gt;And then things grind to a halt.&lt;&#x2F;p&gt;
&lt;p&gt;As Khem recently shared,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;daily.himvis.com&#x2F;0032-on-strategy-4&#x2F;&quot;&gt;Maintenance is costlier than development&lt;&#x2F;a&gt;,
so even though development is important today, maintenance is more important –
for tomorrow.&lt;&#x2F;p&gt;
&lt;p&gt;Part of YOUR Platform should be selecting technologies that can be updated
regularly with little pain, and a process to do this.&lt;&#x2F;p&gt;
&lt;p&gt;It is the question of paying a little bit continuously, or a lot all at once
later, and the latter is often so painful that in many cases it is impractical.&lt;&#x2F;p&gt;
&lt;p&gt;Investing in YOUR Platforming compounds positive gains – neglecting technical
debt compounds negative gains.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🆚 What is the difference between YOUR Platform and other platforms?</title>
        <published>2024-10-01T00:00:00+00:00</published>
        <updated>2024-10-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0046-your-platform-vs-others/"/>
        <id>https://bec-systems.com/blog/0046-your-platform-vs-others/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0046-your-platform-vs-others/">&lt;p&gt;We all use other platforms – operating systems, cloud services, middle-ware,
hardware modules, etc.&lt;&#x2F;p&gt;
&lt;p&gt;It is tempting when building a product to piggyback entirely on someone else’s
platform (AWS, .NET, one of the 100’s of IoT Platforms, etc.)&lt;&#x2F;p&gt;
&lt;p&gt;Society tells us – you can’t host your own service, deploy your own updates,
design your own hardware, implement reliable systems, etc.&lt;&#x2F;p&gt;
&lt;p&gt;But at a small&#x2F;medium scale, none of these things are very hard.&lt;&#x2F;p&gt;
&lt;p&gt;If you do them, you can simplify and optimize for your needs.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform is partly the ability to leverage other platforms, but also to
build your own – where you are in control of the critical integration points.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💪 Good enough is not good enough</title>
        <published>2024-09-27T00:00:00+00:00</published>
        <updated>2024-09-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0045-good-enough/"/>
        <id>https://bec-systems.com/blog/0045-good-enough/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0045-good-enough/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;good-enough.png&quot; alt=&quot;good enough&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;My grandfather had this sign on his desk for years, and it embodied his
philosophy for work.&lt;&#x2F;p&gt;
&lt;p&gt;He did things right.&lt;&#x2F;p&gt;
&lt;p&gt;He read manuals for his equipment cover to cover.&lt;&#x2F;p&gt;
&lt;p&gt;He understood how things worked.&lt;&#x2F;p&gt;
&lt;p&gt;And because of this, he could fix and maintain machines. Lots of people brought
their machines to him.&lt;&#x2F;p&gt;
&lt;p&gt;Is your product development process trapped in “good enough?”&lt;&#x2F;p&gt;
&lt;p&gt;Do you understand the technology used to build your products?&lt;&#x2F;p&gt;
&lt;p&gt;Have you read the manuals?&lt;&#x2F;p&gt;
&lt;p&gt;Do you know how to fix things when they break?&lt;&#x2F;p&gt;
&lt;p&gt;Is your process maintained? Can you update the pieces?&lt;&#x2F;p&gt;
&lt;p&gt;Platforms are long-term prospects.&lt;&#x2F;p&gt;
&lt;p&gt;And because YOUR Platform is never good enough, over time it gets really good.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚠️ When things go wrong ...</title>
        <published>2024-09-26T00:00:00+00:00</published>
        <updated>2024-09-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0044-when-things-go-wrong/"/>
        <id>https://bec-systems.com/blog/0044-when-things-go-wrong/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0044-when-things-go-wrong/">&lt;p&gt;What do we do?&lt;&#x2F;p&gt;
&lt;p&gt;Do we focus on who&#x2F;what to blame?&lt;&#x2F;p&gt;
&lt;p&gt;Or do we figure out a path forward.&lt;&#x2F;p&gt;
&lt;p&gt;How we are going to prevent this problem in the future?&lt;&#x2F;p&gt;
&lt;p&gt;Not by shaming someone into paralysis, but by fixing the process.&lt;&#x2F;p&gt;
&lt;p&gt;By improving YOUR Platform.&lt;&#x2F;p&gt;
&lt;p&gt;The opportunity for the individual&#x2F;organization who made the mistake to help fix
the process is a graceful way out and preserves their dignity.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚀 Do you own your deployment?</title>
        <published>2024-09-23T00:00:00+00:00</published>
        <updated>2024-09-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0043-do-you-own-your-deployment/"/>
        <id>https://bec-systems.com/blog/0043-do-you-own-your-deployment/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0043-do-you-own-your-deployment/">&lt;p&gt;Saturday morning, I got a call from a customer – something was not working due
to a bug we had deployed Friday (no we don’t have very good tests) 🤫.&lt;&#x2F;p&gt;
&lt;p&gt;The fix was easy, I tested it locally, and then tried to push it to a Git
hosting service we are using, but the Git service was down.&lt;&#x2F;p&gt;
&lt;p&gt;Now what? Our Ansible deployment script pulled directly from git, built the
program, and then deployed it.&lt;&#x2F;p&gt;
&lt;p&gt;While I could reverse engineer the build from the Ansible scripts and do it
manually, that would have taken time and introduced the possibility of another
error.&lt;&#x2F;p&gt;
&lt;p&gt;So I pushed the repo to my Gitea server, tweaked the repo line in the Ansible
script, and deployed the update – not a big deal.&lt;&#x2F;p&gt;
&lt;p&gt;This brings up a question though – we don’t usually think of deployment as
critical infrastructure – not a big deal if it is not working – until you need
to fix something quickly in production.&lt;&#x2F;p&gt;
&lt;p&gt;What if the deployment was wrapped up in some CI&#x2F;CD workflow that only worked in
vendor X’s cloud service?&lt;&#x2F;p&gt;
&lt;p&gt;Maybe simple deployments are actually a better – a shell script that lives in
the project repo that you can run anywhere. This could still be called by a CI
process for the normal workflow.&lt;&#x2F;p&gt;
&lt;p&gt;All computing systems have the potential to fail – it does not matter how big
vendor X is – their stuff can still fail.&lt;&#x2F;p&gt;
&lt;p&gt;Networks occasionally have problems.&lt;&#x2F;p&gt;
&lt;p&gt;DNS can have issues.&lt;&#x2F;p&gt;
&lt;p&gt;Systems get hacked.&lt;&#x2F;p&gt;
&lt;p&gt;No matter how many layers of complexity we pile on top of this.&lt;&#x2F;p&gt;
&lt;p&gt;In networked computer systems, the simplest path to resiliency is the ability to
QUICKLY rebuild systems, whether that is your workstation, laptop, server, or
deployment system.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 What will you improve today?</title>
        <published>2024-09-20T00:00:00+00:00</published>
        <updated>2024-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0042-what-will-you-improve-today/"/>
        <id>https://bec-systems.com/blog/0042-what-will-you-improve-today/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0042-what-will-you-improve-today/">&lt;p&gt;Platforms are all about improvement – at the personal, team, and company
levels.&lt;&#x2F;p&gt;
&lt;p&gt;One approach is to each day write down something you are going to improve and
set aside a small block of time daily to work on it. Make this part of your
personal process.&lt;&#x2F;p&gt;
&lt;p&gt;This does not have to be something big – clean your workspace, create a
checklist for something you don’t enjoy doing, automate something, write some
documentation to help others on the team, write a test for some troublesome
code, refactor something, improve CI&#x2F;CD, …&lt;&#x2F;p&gt;
&lt;p&gt;The internal improvements you do today, while not directly seen by your
customers, will help you deliver something better tomorrow.&lt;&#x2F;p&gt;
&lt;p&gt;What will you improve in YOUR Platform today? Reply and I’ll compile a list and
share it in a future post.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What is the role of vision?</title>
        <published>2024-09-19T00:00:00+00:00</published>
        <updated>2024-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0041-vision/"/>
        <id>https://bec-systems.com/blog/0041-vision/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0041-vision/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0040-preparing-for-the-future&#x2F;&quot;&gt;Yesterday&lt;&#x2F;a&gt;, we
discussed the difficulty in predicting the future and the folly of
“just-in-case” development.&lt;&#x2F;p&gt;
&lt;p&gt;However, we should not discount the need for vision – the sense for where we
need to go in the future.&lt;&#x2F;p&gt;
&lt;p&gt;Not necessarily specifics, but a gut-feel for where things are heading.&lt;&#x2F;p&gt;
&lt;p&gt;Clearly seeing problems that could be solved.&lt;&#x2F;p&gt;
&lt;p&gt;To understand the changes that are happening in our respective industries.&lt;&#x2F;p&gt;
&lt;p&gt;To realize the potential of new technologies that most don’t understand.&lt;&#x2F;p&gt;
&lt;p&gt;This vision does not translate to “just-in-case” feature development, but rather
building a platform that prepares you to meet the future.&lt;&#x2F;p&gt;
&lt;p&gt;Where you can quickly build the features your customers need as you learn the
specifics.&lt;&#x2F;p&gt;
&lt;p&gt;Where iterations cost very little.&lt;&#x2F;p&gt;
&lt;p&gt;Where new features and technologies can be integrated, validated, and deployed
– confidently.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔮 Preparing for the future</title>
        <published>2024-09-18T00:00:00+00:00</published>
        <updated>2024-09-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0040-preparing-for-the-future/"/>
        <id>https://bec-systems.com/blog/0040-preparing-for-the-future/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0040-preparing-for-the-future/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0039-the-platform-test&#x2F;&quot;&gt;Yesterday&lt;&#x2F;a&gt;, we discussed
a fundamental characteristic of a platform: it will go places you never
imagined.&lt;&#x2F;p&gt;
&lt;p&gt;How do we prepare for this?&lt;&#x2F;p&gt;
&lt;p&gt;There are two ways:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Try to predict where things will go in the future and build specific features
into your platform now – just in case …&lt;&#x2F;li&gt;
&lt;li&gt;Build the tooling, processes, and workflows so that you can easily and
confidently add functionality when it is needed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;It is obvious which approach works better – if we try to predict the future (at
least the specifics), we are more often wrong.&lt;&#x2F;p&gt;
&lt;p&gt;We can either try to build the future now, or prepare to meet it as it comes.&lt;&#x2F;p&gt;
&lt;p&gt;The line between these two is often difficult to discern.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✅ The Platform Test</title>
        <published>2024-09-17T00:00:00+00:00</published>
        <updated>2024-09-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0039-the-platform-test/"/>
        <id>https://bec-systems.com/blog/0039-the-platform-test/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0039-the-platform-test/">&lt;p&gt;How do you know if you own YOUR Platform?&lt;&#x2F;p&gt;
&lt;p&gt;If a customer needs a new hardware interface or connector on a product, can you
easily add that?&lt;&#x2F;p&gt;
&lt;p&gt;If a security vulnerability is found in a piece of software in your stack, can
you fix it?&lt;&#x2F;p&gt;
&lt;p&gt;If a customer wants to use a new USB peripheral in a product, can you release a
new SW version with that driver included?&lt;&#x2F;p&gt;
&lt;p&gt;Can you do all the above quickly, easily, and with confidence?&lt;&#x2F;p&gt;
&lt;p&gt;If so, you likely own YOUR Platform.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the thing – embedded systems today are general purpose, updatable, and
expandable. That means people will do things with them that you never imagined.&lt;&#x2F;p&gt;
&lt;p&gt;A fundamental characteristic of a platform is that it will go places you never
imagined.&lt;&#x2F;p&gt;
&lt;p&gt;Are you prepared for that?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🤖 What is the role of AI in your platform?</title>
        <published>2024-09-16T00:00:00+00:00</published>
        <updated>2024-09-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0038-role-of-ai/"/>
        <id>https://bec-systems.com/blog/0038-role-of-ai/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0038-role-of-ai/">&lt;p&gt;We hear much today about how AI is going to do our jobs better than us.&lt;&#x2F;p&gt;
&lt;p&gt;AI is powerful and has access to a lot of information and does a lot of things
humans can’t do.&lt;&#x2F;p&gt;
&lt;p&gt;It is really great at writing shell scripts, boilerplate in programs, figuring
out how to use an API, summarizing public information on the Internet, etc.&lt;&#x2F;p&gt;
&lt;p&gt;But these tasks are not the differentiator.&lt;&#x2F;p&gt;
&lt;p&gt;The real value is going deep.&lt;&#x2F;p&gt;
&lt;p&gt;Information found only in books, which AI does not have access to.&lt;&#x2F;p&gt;
&lt;p&gt;Experience found only in people and encoded in platforms.&lt;&#x2F;p&gt;
&lt;p&gt;AI in a product can be useful for extracting information from YOUR data.&lt;&#x2F;p&gt;
&lt;p&gt;General AI tools are platforms in themselves, but probably not YOUR Platform,
and probably not the creator of the primary value of YOUR Platform.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform is for extracting and leveraging the deep – the value people
need.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 What is the first thing you should implement?</title>
        <published>2024-09-06T00:00:00+00:00</published>
        <updated>2024-09-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0037-update/"/>
        <id>https://bec-systems.com/blog/0037-update/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0037-update/">&lt;p&gt;When building a new system, what is the first thing you implement?&lt;&#x2F;p&gt;
&lt;p&gt;There are a lot of approaches – one is to implement a minimal proof of concept.&lt;&#x2F;p&gt;
&lt;p&gt;However, I think an easy way to update software in any part of the system  (Linux edge devices, microcontrollers, cloud applications) is something that should be done as early as practical.&lt;&#x2F;p&gt;
&lt;p&gt;Requiring a technician to go on-site with a computer and specialized software does not count.&lt;&#x2F;p&gt;
&lt;p&gt;Neither does a multi-step manual process of manually building something, scp’ing files to a server, manually restarting stuff, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Deploying new software to any system should be easy and quick.&lt;&#x2F;p&gt;
&lt;p&gt;A single click, or putting a single file on USB disk and rebooting a device, or merging to main and continuous delivery (CD) delivers our new software to the cloud.&lt;&#x2F;p&gt;
&lt;p&gt;We may think nice update mechanisms are for our customers in production, and they certainly are.&lt;&#x2F;p&gt;
&lt;p&gt;But update tooling also helps us during development.&lt;&#x2F;p&gt;
&lt;p&gt;An easy way to update systems encourages us to do it more often, because it is easy.&lt;&#x2F;p&gt;
&lt;p&gt;We iterate faster.&lt;&#x2F;p&gt;
&lt;p&gt;Fixes and improvements are deployed instantly.&lt;&#x2F;p&gt;
&lt;p&gt;We test more systems during development.&lt;&#x2F;p&gt;
&lt;p&gt;We can easily adapt as we learn more about the problem we are trying to solve.&lt;&#x2F;p&gt;
&lt;p&gt;We can involve more non-technical people in development and testing.&lt;&#x2F;p&gt;
&lt;p&gt;What helps us scale in production also helps us scale during development.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of doing update last, do it first – as an integral part of YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🚫 No Golden Machines</title>
        <published>2024-09-05T00:00:00+00:00</published>
        <updated>2024-09-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0036-no-golden-machines/"/>
        <id>https://bec-systems.com/blog/0036-no-golden-machines/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0036-no-golden-machines/">&lt;p&gt;As humans, we can become attached to “golden” machines.&lt;&#x2F;p&gt;
&lt;p&gt;A very expensive bicycle set up just right, a well-tuned tool, a nicely
configured workstation, a server that we have set up just right …&lt;&#x2F;p&gt;
&lt;p&gt;We like buying expensive things or the iterative process of tweaking things just
right.&lt;&#x2F;p&gt;
&lt;p&gt;However, this generally does not move YOUR Platform forward.&lt;&#x2F;p&gt;
&lt;p&gt;Everything on this earth is ephemeral.&lt;&#x2F;p&gt;
&lt;p&gt;Laptops are damaged. Bicycles are stolen. Tools break. Severs crash.&lt;&#x2F;p&gt;
&lt;p&gt;So then we become obsessed with protecting our golden machines – locks,
excessive security, redundancy, monitoring, etc.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with being over-protective is that it is time-consuming and hinders
our using something in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;We’re afraid to use it in case we might mess it up.&lt;&#x2F;p&gt;
&lt;p&gt;We’re afraid to change it because we don’t understand the history of tweaks.&lt;&#x2F;p&gt;
&lt;p&gt;What if instead we said: “NO GOLDEN MACHINES”&lt;&#x2F;p&gt;
&lt;p&gt;If our laptop gets run over, we can quickly set up a new one.&lt;&#x2F;p&gt;
&lt;p&gt;If the server crashes, we can quickly deploy a new one.&lt;&#x2F;p&gt;
&lt;p&gt;If we need to use a favorite editor on a different computer, it only takes 2
minutes to set it up.&lt;&#x2F;p&gt;
&lt;p&gt;If our bicycle is stolen, we buy another reasonably priced one and have the
skills to set it up.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform is best built from machines that we can easily use, replicate, and
scale, not golden machines that we have to protect.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🙋 How to help yourself?</title>
        <published>2024-09-04T00:00:00+00:00</published>
        <updated>2024-09-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0035-how-to-help-yourself/"/>
        <id>https://bec-systems.com/blog/0035-how-to-help-yourself/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0035-how-to-help-yourself/">&lt;p&gt;Did you ever have the experience going back into a project you have not touched
for 6 months – why did I make this change?&lt;&#x2F;p&gt;
&lt;p&gt;Or did you ever struggle to get all the dependencies installed to build a
project you wrote?&lt;&#x2F;p&gt;
&lt;p&gt;Or did you ever wonder – will this change break something I’m not thinking of?&lt;&#x2F;p&gt;
&lt;p&gt;Or did you ever question – how do we actually deploy this now that it is
updated?&lt;&#x2F;p&gt;
&lt;p&gt;Ironically, when you try really hard to help others use your work –
documentation, tests, CI&#x2F;CD – you are mostly helping your future self.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔎 Seeing patterns</title>
        <published>2024-09-03T00:00:00+00:00</published>
        <updated>2024-09-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0034-seeing-patterns/"/>
        <id>https://bec-systems.com/blog/0034-seeing-patterns/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0034-seeing-patterns/">&lt;p&gt;Patterns are important.&lt;&#x2F;p&gt;
&lt;p&gt;Seeing patterns allows us to simplify things by using common data structures,
re-using code&#x2F;design, finding solutions to common problems, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Being able to see patterns also allows us to troubleshoot effectively.&lt;&#x2F;p&gt;
&lt;p&gt;But, to see patterns, we need to have history and data in a form that is easy to
see and process.&lt;&#x2F;p&gt;
&lt;p&gt;For troubleshooting, this may be a common place to collect notes – say every
time a system fails, we record the incident in a single shared Google Doc.&lt;&#x2F;p&gt;
&lt;p&gt;Tagging is also effective – we might tag a dataset for different types of
events, and then be able to quickly filter on different combinations of tags.&lt;&#x2F;p&gt;
&lt;p&gt;To see patterns in source code, we need to have source code organized such that
it is easy to see and navigate through all of it – for most of this, this means
a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;monoliths-and-monorepos&#x2F;202&quot;&gt;monorepo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Transparency is critical – can we easily see things other people are working
on, or is each person or team working in walled-off silos?&lt;&#x2F;p&gt;
&lt;p&gt;Patterns are not invented, but rather discovered.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms are all about identifying and leveraging patterns.&lt;&#x2F;p&gt;
&lt;p&gt;And seeing patterns requires transparency, thoughtful organization of our
assets, and rigorous logging of what happens over time.&lt;&#x2F;p&gt;
&lt;p&gt;Do these things, and patterns will naturally emerge, for YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🗝️ What is the best tool for private Git repos?</title>
        <published>2024-09-02T00:00:00+00:00</published>
        <updated>2024-09-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0033-best-tool-for-private-git/"/>
        <id>https://bec-systems.com/blog/0033-best-tool-for-private-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0033-best-tool-for-private-git/">&lt;p&gt;Several days ago, I
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0030-modern-git-tools&#x2F;&quot;&gt;made a case&lt;&#x2F;a&gt; for using
Github to engage users around your OSS project.&lt;&#x2F;p&gt;
&lt;p&gt;But is this the hammer you should use to drive every nail?&lt;&#x2F;p&gt;
&lt;p&gt;For private projects, I think Gitea is actually better in most respects.&lt;&#x2F;p&gt;
&lt;p&gt;It is very fast, clean, and most of the basic functions work as good or better
than Github.&lt;&#x2F;p&gt;
&lt;p&gt;And you can host all but the largest repos on a $5&#x2F;mo Linode with unlimited
users.&lt;&#x2F;p&gt;
&lt;p&gt;Groups and permissions are very flexible.&lt;&#x2F;p&gt;
&lt;p&gt;Branch protection works.&lt;&#x2F;p&gt;
&lt;p&gt;In all, it is very good!&lt;&#x2F;p&gt;
&lt;p&gt;I wrote an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;ansible-role-gitea&quot;&gt;Ansible role&lt;&#x2F;a&gt; that
works very well for updating your Gitea instance. I’ve updated through ~70 Gitea
versions with almost no problems.&lt;&#x2F;p&gt;
&lt;p&gt;Gitea may be a better option for YOUR internal Platform – more details to
follow …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🐶 Lessons from a 1-year old dog</title>
        <published>2024-08-30T00:00:00+00:00</published>
        <updated>2024-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0032-lessons-from-a-dog/"/>
        <id>https://bec-systems.com/blog/0032-lessons-from-a-dog/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0032-lessons-from-a-dog/">&lt;p&gt;As I was going through my morning routine with our 1.3 year old dog, Reese, who
is very energetic, it occurred to me how well short training sessions &lt;em&gt;every&lt;&#x2F;em&gt;
morning are working.&lt;&#x2F;p&gt;
&lt;p&gt;A 12hr session with her once a month will do virtually nothing.&lt;&#x2F;p&gt;
&lt;p&gt;Improvement is not really what my dog wants to be doing – she would rather
chase squirrels, dig holes, jump on people – do something heroic.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise, most of us don’t really want to clean our office, write a CI script,
refactor some messy code – we want to design things, code a new feature, make a
sale, build 1000 widgets, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Improvement is hard and sometimes painful.&lt;&#x2F;p&gt;
&lt;p&gt;And the pain is proportional to the size of the improvement dose we are facing.&lt;&#x2F;p&gt;
&lt;p&gt;If we can break it down into small enough chunks, it is manageable, and actually
enjoyable.&lt;&#x2F;p&gt;
&lt;p&gt;Platform improvements are rarely moments of deep inspiration, but rather just
buckling down and doing what you know should be done.&lt;&#x2F;p&gt;
&lt;p&gt;Discipline.&lt;&#x2F;p&gt;
&lt;p&gt;And this sometimes works best if you schedule a time block every day – 25
minutes, start the timer, go …&lt;&#x2F;p&gt;
&lt;p&gt;You only have 25m, get going, now!&lt;&#x2F;p&gt;
&lt;p&gt;And after our morning walk, Reese now walks toward where her leash is hanging –
she is actually looking forward to these short, regular sessions.&lt;&#x2F;p&gt;
&lt;p&gt;Improvement is best continuous.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;reese.png&quot; alt=&quot;dog&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 Solving problems or symptoms?</title>
        <published>2024-08-29T00:00:00+00:00</published>
        <updated>2024-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0031-solving-problems-or-symptoms/"/>
        <id>https://bec-systems.com/blog/0031-solving-problems-or-symptoms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0031-solving-problems-or-symptoms/">&lt;p&gt;The following quotes from the book “The One-Straw Revolution” caught my eye:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The more elaborate the countermeasures, the more complicated the problems
become. … When a decision is made to cope with the symptoms of a problem, it
is generally assumed that the corrective measures will solve the problem
itself. They seldom do. Engineers cannot seem to get this through their heads.
These countermeasures are all based on too narrow a definition of what is
wrong.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Although Masanobu Fukuoka’s book is about agricultural systems, the concepts
apply to systems in general.&lt;&#x2F;p&gt;
&lt;p&gt;With security, do we pile on additional layers of checking, detection, etc., or
do we use a simpler and more secure technology to start with?&lt;&#x2F;p&gt;
&lt;p&gt;For reliability, do we implement elaborate distributed&#x2F;redundant systems that
check each other, or improve our testing of a single system so that it rarely
fails?&lt;&#x2F;p&gt;
&lt;p&gt;When deployment mistakes are made, do we add more bureaucracy and red tape, or
do we improve the process&#x2F;tooling such that it is difficult to make the mistake
in the first place?&lt;&#x2F;p&gt;
&lt;p&gt;When something is not working, do we add on layers of complexity to fix it, or
try to simplify and identify the root cause?&lt;&#x2F;p&gt;
&lt;p&gt;One way to improve this is ask “why?” five times.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🐙 Github and why does it matter?</title>
        <published>2024-08-28T00:00:00+00:00</published>
        <updated>2024-08-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0030-modern-git-tools/"/>
        <id>https://bec-systems.com/blog/0030-modern-git-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0030-modern-git-tools/">&lt;p&gt;For the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0028-what-makes-a-good-bsp&#x2F;&quot;&gt;last&lt;&#x2F;a&gt; two
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0029-tracking-upstream&#x2F;&quot;&gt;days&lt;&#x2F;a&gt;, we have been
discussing aspects of several high-quality Yocto BSPs.&lt;&#x2F;p&gt;
&lt;p&gt;Another characteristic of these three BSPs is that they are all hosted on
Github.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, there are many other platforms you can host Git repositories on.&lt;&#x2F;p&gt;
&lt;p&gt;You can easily do your own Git hosting (I personally use Gitea for private Git
repos).&lt;&#x2F;p&gt;
&lt;p&gt;But, for better or worse, if you want to engage with a world-wide community
around a software project, Github is the easiest, lowest friction place to do
that.&lt;&#x2F;p&gt;
&lt;p&gt;Most developers have a Github account, and this means they can easily create
issue tickets, submit pull requests etc.&lt;&#x2F;p&gt;
&lt;p&gt;Some projects, like the Linux kernel, are so popular and well-established it
does not really matter how they interact with the community. They can be rude,
use older methods of handling changes like patches on a mail-list, etc. and it
does not matter. It might even be argued that these “barriers to entry” are
helpful in weeding out the noise in a very large project. Perhaps this is true.&lt;&#x2F;p&gt;
&lt;p&gt;But for most of us, we are not at that scale. We don’t have that luxury. Even
most downstream Linux trees are hosted on Github these days.&lt;&#x2F;p&gt;
&lt;p&gt;If users find it difficult to engage and interact with us, they won’t bother,
especially the younger generation of developers.&lt;&#x2F;p&gt;
&lt;p&gt;Most developers are (rightly) focused on their projects – their work, not
yours. Thus, it is an act of generosity if they take the time to interact with
or contribute to a supplier’s project. They are doing it because they want to –
not because they have to.&lt;&#x2F;p&gt;
&lt;p&gt;And if users can’t easily interact with a supplier, does that supplier really
understand their concerns?&lt;&#x2F;p&gt;
&lt;p&gt;Github has set a new standard for transparency, tooling, and interaction. It is
the lowest friction platform for social coding. And social matters today.&lt;&#x2F;p&gt;
&lt;p&gt;This all has implications for how users&#x2F;customers interact with YOUR Platform
(if public) and how you select technology for YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔁 Tracking upstream and why does it matter?</title>
        <published>2024-08-27T00:00:00+00:00</published>
        <updated>2024-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0029-tracking-upstream/"/>
        <id>https://bec-systems.com/blog/0029-tracking-upstream/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0029-tracking-upstream/">&lt;p&gt;Yesterday, we discussed three Yocto BSP layers that are exceptional:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OE4T&#x2F;meta-tegra&quot;&gt;meta-tegra&lt;&#x2F;a&gt; (69 contributors)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Freescale&#x2F;meta-freescale&quot;&gt;meta-freescale&lt;&#x2F;a&gt; (174
contributors)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;agherzan&#x2F;meta-raspberrypi&quot;&gt;meta-raspberrypi&lt;&#x2F;a&gt; (157
contributors)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above three layers make an effort to keep up with upstream developments.
This may mean regularly merging upstream, doing a build, fixing issues –
keeping up.&lt;&#x2F;p&gt;
&lt;p&gt;As a result, they are always ready for the next release of the Linux kernel,
Yocto, whatever.&lt;&#x2F;p&gt;
&lt;p&gt;A little bit of continuous effort is much easier than a monumental effort every
four years.&lt;&#x2F;p&gt;
&lt;p&gt;Why does this matter for small teams&#x2F;companies?&lt;&#x2F;p&gt;
&lt;p&gt;There are many reasons, but when working with complex open-source software,
we’ll eventually need support&#x2F;help.&lt;&#x2F;p&gt;
&lt;p&gt;And this help typically comes from the community around open-source projects.&lt;&#x2F;p&gt;
&lt;p&gt;And the community is focused on the current development, not a 4-year LTS
release.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the latest releases are where security problems get fixed,
features implemented, and value added.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform benefits most from being where the value is being created.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔧 What makes a good Yocto BSP?</title>
        <published>2024-08-26T00:00:00+00:00</published>
        <updated>2024-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0028-what-makes-a-good-bsp/"/>
        <id>https://bec-systems.com/blog/0028-what-makes-a-good-bsp/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0028-what-makes-a-good-bsp/">&lt;p&gt;As we evaluate technology to use in our platforms, Yocto Embedded Linux BSPs
often come into the mix.&lt;&#x2F;p&gt;
&lt;p&gt;Recently &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;&quot;&gt;we talked&lt;&#x2F;a&gt; with Matt Madison, who maintains the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OE4T&#x2F;meta-tegra&quot;&gt;meta-tegra&lt;&#x2F;a&gt; BSP layer, which provides Yocto
support for Nvidia’s embedded processors, which are increasingly becoming
popular in edge AI applications.&lt;&#x2F;p&gt;
&lt;p&gt;We are using meta-tegra in several projects, and it has been a good experience.&lt;&#x2F;p&gt;
&lt;p&gt;What came out of our discussion is that &lt;strong&gt;user&#x2F;community involvement&lt;&#x2F;strong&gt; is what
makes a good BSP.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;agherzan&#x2F;meta-raspberrypi&quot;&gt;meta-freescale&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;agherzan&#x2F;meta-raspberrypi&quot;&gt;meta-raspberrypi&lt;&#x2F;a&gt; are other
examples of community-oriented BSP layers that are very high quality.&lt;&#x2F;p&gt;
&lt;p&gt;Chip makers have different priorities and concerns than users. And the only way
to understand your users is to get them involved. And the best way to get them
involved is to work on an OSS project together.&lt;&#x2F;p&gt;
&lt;p&gt;We’ve run the experiment in the Yocto BSP space for 14 years, and the results
are in.&lt;&#x2F;p&gt;
&lt;p&gt;When evaluating a complex technology like processors that rely on open-source,
if a supplier does include their users in the development process, there is a
good chance they don’t really understand your concerns.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⏰ The present or the future?</title>
        <published>2024-08-23T00:00:00+00:00</published>
        <updated>2024-08-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0027-the-present-or-the-future/"/>
        <id>https://bec-systems.com/blog/0027-the-present-or-the-future/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0027-the-present-or-the-future/">&lt;p&gt;Planning has its place – we need a vision for where we are going.&lt;&#x2F;p&gt;
&lt;p&gt;But YOUR Platform is best focused on the present, not the future.&lt;&#x2F;p&gt;
&lt;p&gt;Because the future of a complex system is pretty hard to predict.&lt;&#x2F;p&gt;
&lt;p&gt;When we focus on improving our current efforts with refactoring, testing,
automation, documentation, CI&#x2F;CD, etc. in the simplest way possible …&lt;&#x2F;p&gt;
&lt;p&gt;We pave the way to the future, by reducing friction in the present.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👥 Platform != People</title>
        <published>2024-08-22T00:00:00+00:00</published>
        <updated>2024-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0026-platform-not-equal-people/"/>
        <id>https://bec-systems.com/blog/0026-platform-not-equal-people/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0026-platform-not-equal-people/">&lt;p&gt;The right people in your organization is absolutely essential – no question
about that.&lt;&#x2F;p&gt;
&lt;p&gt;And dealing with “people issues” is a critical and essential skill.&lt;&#x2F;p&gt;
&lt;p&gt;But, if your organization is dependent on a star individual and you are in big
trouble when he&#x2F;she is gone, then you don’t have a platform.&lt;&#x2F;p&gt;
&lt;p&gt;We need great people, but if they can’t work in the context of YOUR Platform,
then you will have trouble scaling and hit a major speed bump when they leave.&lt;&#x2F;p&gt;
&lt;p&gt;People come and go.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform is what gives your business the consistency and resiliency to keep
going – smoothly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✅ What is the simplest form of automation?</title>
        <published>2024-08-21T00:00:00+00:00</published>
        <updated>2024-08-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0025-what-is-the-simplest-form-of-automation/"/>
        <id>https://bec-systems.com/blog/0025-what-is-the-simplest-form-of-automation/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0025-what-is-the-simplest-form-of-automation/">&lt;p&gt;The simplest form of automation is a checklist or playbook.&lt;&#x2F;p&gt;
&lt;p&gt;If there is something you need to do more than a couple times that involves
multiple steps, a checklist is a great place to start.&lt;&#x2F;p&gt;
&lt;p&gt;Then we no longer have to dread doing a multi-step task because it is easy –
all we need to do is go through the documented steps.&lt;&#x2F;p&gt;
&lt;p&gt;Checklists are surprisingly effective at reducing friction and mistakes. Many of
us do this personally for things like travelling as it is easy to forget
something if we don’t.&lt;&#x2F;p&gt;
&lt;p&gt;And the beautiful thing about checklists is they can easily be turned into more
advanced forms of automation (scripts, continuous delivery, etc) because you
have already thought through and debugged the process, which is often the hard
part and where we get stuck.&lt;&#x2F;p&gt;
&lt;p&gt;Checklists can turn into scripts, which can turn into continuous delivery.&lt;&#x2F;p&gt;
&lt;p&gt;Part of YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>📈 How does your product value increase after the initial sale?</title>
        <published>2024-08-20T00:00:00+00:00</published>
        <updated>2024-08-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0024-how-does-you-producct-value-increase/"/>
        <id>https://bec-systems.com/blog/0024-how-does-you-producct-value-increase/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0024-how-does-you-producct-value-increase/">&lt;p&gt;How does your product increase in value after the sale?&lt;&#x2F;p&gt;
&lt;p&gt;Software&#x2F;Firmware&#x2F;Cloud updates.&lt;&#x2F;p&gt;
&lt;p&gt;Software is soft for a reason – it is meant to be changed, improved.&lt;&#x2F;p&gt;
&lt;p&gt;And sometimes we install “apps” to add new functionality.&lt;&#x2F;p&gt;
&lt;p&gt;And with this improvement comes increased value.&lt;&#x2F;p&gt;
&lt;p&gt;It is kind of like your phone – with each new OS update, things generally get
better.&lt;&#x2F;p&gt;
&lt;p&gt;Each app you install (potentially) provides some utility.&lt;&#x2F;p&gt;
&lt;p&gt;Why, because modern phones are platforms.&lt;&#x2F;p&gt;
&lt;p&gt;Is your product a platform, or is it at least built and deployed using a
platform?&lt;&#x2F;p&gt;
&lt;p&gt;Does its value increase over time?&lt;&#x2F;p&gt;
&lt;p&gt;At industrial product scale, you don’t necessarily need to support user
installed apps, but you need to at least be able to add functionality, fix
things, and deploy these updates – efficiently.&lt;&#x2F;p&gt;
&lt;p&gt;How? With YOUR Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚠️ Hack-it, ship-it, forget-it ...</title>
        <published>2024-08-19T00:00:00+00:00</published>
        <updated>2024-08-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0023-hack-it-ship-it-forget-it/"/>
        <id>https://bec-systems.com/blog/0023-hack-it-ship-it-forget-it/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0023-hack-it-ship-it-forget-it/">&lt;p&gt;Hack-it, ship-it, forget-it … is a race to the bottom where cost is the only
thing that matters.&lt;&#x2F;p&gt;
&lt;p&gt;The initial delivery is what your customer gets – forever.&lt;&#x2F;p&gt;
&lt;p&gt;These types of products only depreciate.&lt;&#x2F;p&gt;
&lt;p&gt;And cannot be maintained.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Alternatively, the value of your product can &lt;em&gt;increase&lt;&#x2F;em&gt; over time.&lt;&#x2F;p&gt;
&lt;p&gt;Where you fix problems quickly.&lt;&#x2F;p&gt;
&lt;p&gt;And add features in a timely fashion as needs&#x2F;markets change.&lt;&#x2F;p&gt;
&lt;p&gt;Where you overcome the laws of chaos and improve instead of decay.&lt;&#x2F;p&gt;
&lt;p&gt;Because you own YOUR Platform.&lt;&#x2F;p&gt;
&lt;p&gt;Which business do you want to be in?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏆 What is the #1 purpose of YOUR Platform?</title>
        <published>2024-08-16T00:00:00+00:00</published>
        <updated>2024-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0022-no1-purpose-of-your-platform/"/>
        <id>https://bec-systems.com/blog/0022-no1-purpose-of-your-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0022-no1-purpose-of-your-platform/">&lt;p&gt;The purpose of YOUR Platform is to reduce friction in delivering value to your
customers.&lt;&#x2F;p&gt;
&lt;p&gt;We are in business to deliver value to our customers.&lt;&#x2F;p&gt;
&lt;p&gt;If we can do this better, we can deliver more value.&lt;&#x2F;p&gt;
&lt;p&gt;There are lots of ways we can do this.&lt;&#x2F;p&gt;
&lt;p&gt;Automation.&lt;&#x2F;p&gt;
&lt;p&gt;Better tools.&lt;&#x2F;p&gt;
&lt;p&gt;Additional features.&lt;&#x2F;p&gt;
&lt;p&gt;Quality&#x2F;stability improvements.&lt;&#x2F;p&gt;
&lt;p&gt;Release more often.&lt;&#x2F;p&gt;
&lt;p&gt;Respond more quickly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌱 Culture</title>
        <published>2024-08-15T00:00:00+00:00</published>
        <updated>2024-08-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0021-platform-culture/"/>
        <id>https://bec-systems.com/blog/0021-platform-culture/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0021-platform-culture/">&lt;p&gt;What type of culture do platforms thrive in?&lt;&#x2F;p&gt;
&lt;p&gt;Where ideas are valued and evaluated on merit and truth.&lt;&#x2F;p&gt;
&lt;p&gt;Where initiative is rewarded.&lt;&#x2F;p&gt;
&lt;p&gt;Where mistakes result in process improvements, not scoldings.&lt;&#x2F;p&gt;
&lt;p&gt;Where openness and transparency are the standard.&lt;&#x2F;p&gt;
&lt;p&gt;Where anyone can improve anything in the system – there is no protecting turf.&lt;&#x2F;p&gt;
&lt;p&gt;Where OSS tools are used when possible.&lt;&#x2F;p&gt;
&lt;p&gt;Where things are continuously improved.&lt;&#x2F;p&gt;
&lt;p&gt;Platform cultures are organic.&lt;&#x2F;p&gt;
&lt;p&gt;We can learn a lot from Open Source projects here …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏗️ Three levels of YOUR Platform</title>
        <published>2024-08-14T00:00:00+00:00</published>
        <updated>2024-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0020-three-levels-of-your-platform/"/>
        <id>https://bec-systems.com/blog/0020-three-levels-of-your-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0020-three-levels-of-your-platform/">&lt;p&gt;We can look at platforms at three levels.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;platform-levels.png&quot; alt=&quot;platform levels&quot; style=&quot;zoom:50%;&quot; &#x2F;&gt;
&lt;p&gt;Your personal platform is the know-how that you can personally reuse from
task-to-task, project-to-project, and job-to-job. But, it is not real useful
outside yourself.&lt;&#x2F;p&gt;
&lt;p&gt;A product platform may be what a team uses to efficiently build, maintain, and
produce variants of a product.&lt;&#x2F;p&gt;
&lt;p&gt;A company platform is when you are able to reuse know-how, technology, tools,
and processes on one product and leverage that on the next product, and when an
improvement on one product improves another.&lt;&#x2F;p&gt;
&lt;p&gt;All three are valuable, but the higher up the stack you can go, the higher the
value.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👣 What are the first steps?</title>
        <published>2024-08-13T00:00:00+00:00</published>
        <updated>2024-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0019-what-are-the-first-steps/"/>
        <id>https://bec-systems.com/blog/0019-what-are-the-first-steps/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0019-what-are-the-first-steps/">&lt;p&gt;What are the first steps to building YOUR Platform?&lt;&#x2F;p&gt;
&lt;p&gt;Ironically, the first step is not some grandiose new Platform vision, but rather
to set your house in order.&lt;&#x2F;p&gt;
&lt;p&gt;Clean up what you already have.&lt;&#x2F;p&gt;
&lt;p&gt;Fix legacy code (code without tests).&lt;&#x2F;p&gt;
&lt;p&gt;Set up CI&#x2F;CD.&lt;&#x2F;p&gt;
&lt;p&gt;Implement end-to-end testing so that you can deploy with confidence.&lt;&#x2F;p&gt;
&lt;p&gt;Write documentation.&lt;&#x2F;p&gt;
&lt;p&gt;This paves the highway for efficiently moving forward, instead of slogging
through the mud.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔄 What is YOUR Platform? (v2)</title>
        <published>2024-08-12T00:00:00+00:00</published>
        <updated>2024-08-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0018-what-is-a-platform-v2/"/>
        <id>https://bec-systems.com/blog/0018-what-is-a-platform-v2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0018-what-is-a-platform-v2/">&lt;p&gt;Had a nice visit with &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rodaparicio.com&#x2F;&quot;&gt;Rod&lt;&#x2F;a&gt; and he asked me to
describe what a Platform is in 20 words or less, so here we go:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;YOUR Platform is the collection of technology, tools, and processes that
enable&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; &lt;strong&gt;&lt;em&gt;you to differentiate and consistently deliver your products and
services.&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;sorry Rod, that is 22 words :-)&lt;&#x2F;p&gt;
&lt;p&gt;We have &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0004-what-is-a-platform&#x2F;&quot;&gt;discussed&lt;&#x2F;a&gt; this
before, but I want to revisit this question occasionally and see if the
definition improves over time.&lt;&#x2F;p&gt;
&lt;p&gt;What got added this time is “differentiate” and “consistently”.&lt;&#x2F;p&gt;
&lt;p&gt;Thoughts?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>❓ But what if ...</title>
        <published>2024-08-08T00:00:00+00:00</published>
        <updated>2024-08-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0017-but-what-if/"/>
        <id>https://bec-systems.com/blog/0017-but-what-if/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0017-but-what-if/">&lt;p&gt;In the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;blog&#x2F;0016-you-are-not-google&#x2F;&quot;&gt;last post&lt;&#x2F;a&gt;, we
discussed the fallacy of using complex technology when the scale does not justify
it.&lt;&#x2F;p&gt;
&lt;p&gt;But, what if we get a lot more customers, or sell a lot more systems? Should we
not plan for the future now? Use technologies now that will work at large scale?
We don’t want to paint ourselves into a corner such that we end up with a system
that won’t meet our needs in the future.&lt;&#x2F;p&gt;
&lt;p&gt;Certainly, we should keep the future in mind, but the most important way to plan
for the future is to streamline your processes and development workflow now so
that you can continually move toward the future as it comes.&lt;&#x2F;p&gt;
&lt;p&gt;NOT try to implement the future now. That is costly, and you’ll never get it
right that way.&lt;&#x2F;p&gt;
&lt;p&gt;Some decisions are important now and some are not.&lt;&#x2F;p&gt;
&lt;p&gt;You don’t need to use Kubernetes now – you can add that in later. But it is
important to use some type of automated configuration and deployment – perhaps
a simpler solution like a simple Github Action, or Ansible.&lt;&#x2F;p&gt;
&lt;p&gt;The same with micro-services. It is easy to split things apart later as it makes
sense. But it is difficult to deal with a mess that is prematurely split up.&lt;&#x2F;p&gt;
&lt;p&gt;You can plan by using a decoupled architecture, data structures that are
flexible, and modern programming languages that are efficient.&lt;&#x2F;p&gt;
&lt;p&gt;If you have an efficient workflow where it is easy to make and deploy changes,
the correct architecture will naturally emerge. You will continually simplify
things as you see common patterns.&lt;&#x2F;p&gt;
&lt;p&gt;And simple patterns are what scale to any problem.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔍 You are not Google</title>
        <published>2024-08-07T00:00:00+00:00</published>
        <updated>2024-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0016-you-are-not-google/"/>
        <id>https://bec-systems.com/blog/0016-you-are-not-google/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0016-you-are-not-google/">&lt;p&gt;A blog article published 2017 titled
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.bradfieldcs.com&#x2F;you-are-not-google-84912cf44afb&quot;&gt;You Are Not Google&lt;&#x2F;a&gt;
is a good read. This article makes the case that most companies are not
operating at the size of Google, Amazon, and LinkedIn. Thus, most of us are
solving different problems than the big 5 tech companies.&lt;&#x2F;p&gt;
&lt;p&gt;YOUR Platform needs to fit your problems at your scale.&lt;&#x2F;p&gt;
&lt;p&gt;If one server will work, then you are saving yourself untold pain and suffering
by not pre-maturely building a distributed system.&lt;&#x2F;p&gt;
&lt;p&gt;If one monolothic application can run your product, then you are saving a lot of
hassle not implementing microservices up front.&lt;&#x2F;p&gt;
&lt;p&gt;Keep it simple – you can move to distributed micro-services later – AFTER you
succeed at a smaller scale.&lt;&#x2F;p&gt;
&lt;p&gt;And if you succeed at small scale, then there will be plenty of resources to
adjust your architecture later.&lt;&#x2F;p&gt;
&lt;p&gt;The quicker you can get to a MVP, the better, and simple gets you there quicker.&lt;&#x2F;p&gt;
&lt;p&gt;But what if ??? … stay tuned :-)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>💰 Owning YOUR platform is not more expensive</title>
        <published>2024-08-06T00:00:00+00:00</published>
        <updated>2024-08-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0015-owning-your-platform-is-not-more-expensive/"/>
        <id>https://bec-systems.com/blog/0015-owning-your-platform-is-not-more-expensive/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0015-owning-your-platform-is-not-more-expensive/">&lt;p&gt;Owning your platform sounds expensive.&lt;&#x2F;p&gt;
&lt;p&gt;“We can’t afford ops people to manage servers.”&lt;&#x2F;p&gt;
&lt;p&gt;“Security is scary.”&lt;&#x2F;p&gt;
&lt;p&gt;“We don’t want to manage a database.”&lt;&#x2F;p&gt;
&lt;p&gt;However, at the scale of most industrial products, none of these things are very
hard.&lt;&#x2F;p&gt;
&lt;p&gt;A couple servers can easily handle all your traffic.&lt;&#x2F;p&gt;
&lt;p&gt;A backup and restore plan can handle failures in most cases. Redundancy and
high-availability are overkill.&lt;&#x2F;p&gt;
&lt;p&gt;Cloud services require management too – often you end of managing the cost
instead of the fundamental issues listed above. Six of one, half-dozen of the
other – take your pick. And then you still have to deal with problems – often
due to the distributed nature of cloud services where the network is the weak
link.&lt;&#x2F;p&gt;
&lt;p&gt;See DHH’s posts on
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;why-were-leaving-the-cloud&#x2F;697&quot;&gt;“leaving the cloud”&lt;&#x2F;a&gt;
for an example. They are saving millions owning and managing their own servers
and it is not any more work.&lt;&#x2F;p&gt;
&lt;p&gt;You can hitch up to one of the major cloud vendors and go all in on their
services – that is what everyone else is doing.&lt;&#x2F;p&gt;
&lt;p&gt;Or you can do something different. Take the technology that is being developed
for the cloud, use the cloud where it make sense, and then optimize for YOUR
Platform.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>⚖️ False vs Real Platform Development</title>
        <published>2024-08-05T00:00:00+00:00</published>
        <updated>2024-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0014-real-vs-false-platform-development/"/>
        <id>https://bec-systems.com/blog/0014-real-vs-false-platform-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0014-real-vs-false-platform-development/">&lt;p&gt;A common objection to investing in a platform is that it is “too expensive.”&lt;&#x2F;p&gt;
&lt;p&gt;“We want to get it right, lock it down, and then crank out our product and make
some $$$.”&lt;&#x2F;p&gt;
&lt;p&gt;Many managers and owners are wary of platform development because they have
experienced &lt;em&gt;false&lt;&#x2F;em&gt; platform development – endless tinkering, the costly
pursuit of perfection, etc.&lt;&#x2F;p&gt;
&lt;p&gt;However, real platform development is focused on shipping as soon as possible
and then improving.&lt;&#x2F;p&gt;
&lt;p&gt;Real platform development is realizing that complex, connected systems are
dynamic, living things that need maintained. They do not operate in isolation.&lt;&#x2F;p&gt;
&lt;p&gt;Real platform developers have the humility to realize they can’t see and
understand the big picture up front until they build something and get feedback.&lt;&#x2F;p&gt;
&lt;p&gt;The key to controlling costs is not locking things down such they cannot change,
but rather the opposite – improving your process so that improvements are
efficient to develop and and painless to test and deploy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎆 Do something different</title>
        <published>2024-08-02T00:00:00+00:00</published>
        <updated>2024-08-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0013-doing-something-different/"/>
        <id>https://bec-systems.com/blog/0013-doing-something-different/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0013-doing-something-different/">&lt;p&gt;If you only build on other people’s platforms, how are you different?&lt;&#x2F;p&gt;
&lt;p&gt;And if you are not different, what value are you providing?&lt;&#x2F;p&gt;
&lt;p&gt;We are not talking different for the sake of being different – outlandish,
rebel, etc.&lt;&#x2F;p&gt;
&lt;p&gt;We are talking being different in the sense of offering something better –
something that no one else is doing.&lt;&#x2F;p&gt;
&lt;p&gt;Something you can do pretty well.&lt;&#x2F;p&gt;
&lt;p&gt;Something that helps others.&lt;&#x2F;p&gt;
&lt;p&gt;And to do this, you need to own YOUR Platform, otherwise, why would anyone come
to you?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🐜 The smaller you are, the more import YOUR Platform is</title>
        <published>2024-08-01T00:00:00+00:00</published>
        <updated>2024-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0012-smaller-more-important-platform/"/>
        <id>https://bec-systems.com/blog/0012-smaller-more-important-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0012-smaller-more-important-platform/">&lt;p&gt;This may seem like a contadiction – how can small companies afford to own and
control their Platform? Should not this all be outsourced? “Platforms is what
large companies do.”&lt;&#x2F;p&gt;
&lt;p&gt;Actually, the reverse is true. Netflix can afford to build on AWS and be locked
into the AWS platform because they have enough volume that they have clout and
the ability to negotiate. Amazon will make sure Netflix gets what they need.&lt;&#x2F;p&gt;
&lt;p&gt;Small companies cannot get this type of support.&lt;&#x2F;p&gt;
&lt;p&gt;Does this mean “small company” should never use AWS? No, certainly not – AWS is
a good option for many things.&lt;&#x2F;p&gt;
&lt;p&gt;But it does mean that we only use stuff in AWS that we can migrate elsewhere if
needed.&lt;&#x2F;p&gt;
&lt;p&gt;Use managed Postgres instead of some proprietary AWS.db.&lt;&#x2F;p&gt;
&lt;p&gt;Use NATS running on EC2 or managed at Synadia instead of a proprietary event
system.&lt;&#x2F;p&gt;
&lt;p&gt;Owning YOUR Platform does not mean you build all of it, but rather you have some
level of control over it. You have options.&lt;&#x2F;p&gt;
&lt;p&gt;And the smaller you are, the more important this is.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😨 Control is a scary thing</title>
        <published>2024-07-31T00:00:00+00:00</published>
        <updated>2024-07-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0011-control-is-scary/"/>
        <id>https://bec-systems.com/blog/0011-control-is-scary/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0011-control-is-scary/">&lt;p&gt;Control is a scary thing – because then we are responsible.&lt;&#x2F;p&gt;
&lt;p&gt;And if we are responsible, then we can’t blame someone else.&lt;&#x2F;p&gt;
&lt;p&gt;But if we are not responsible for anything, then what are we doing?&lt;&#x2F;p&gt;
&lt;p&gt;How are we adding value?&lt;&#x2F;p&gt;
&lt;p&gt;Why would anyone want what we are doing?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎛️ What is control?</title>
        <published>2024-07-30T00:00:00+00:00</published>
        <updated>2024-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0010-what-is-control/"/>
        <id>https://bec-systems.com/blog/0010-what-is-control/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0010-what-is-control/">&lt;p&gt;What is control in the context of Your Platform?&lt;&#x2F;p&gt;
&lt;p&gt;Control is simply the ability to respond to opportunities and problems.&lt;&#x2F;p&gt;
&lt;p&gt;In modern systems we are very dependent on others as there is no way we can do
everything ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;But we can also strategically retain enough control so that we can adjust and
adapt as conditions require.&lt;&#x2F;p&gt;
&lt;p&gt;We have more options today than ever before.&lt;&#x2F;p&gt;
&lt;p&gt;We may think putting all of our eggs in the “big company” basket is the path to
safety.&lt;&#x2F;p&gt;
&lt;p&gt;But if we open our eyes, we soon realize this does not always work.&lt;&#x2F;p&gt;
&lt;p&gt;“big company” may discontinue a service we depend on.&lt;&#x2F;p&gt;
&lt;p&gt;“big company” may have an outage.&lt;&#x2F;p&gt;
&lt;p&gt;“big company” may have security problems.&lt;&#x2F;p&gt;
&lt;p&gt;There is nothing wrong with using “big company” as long as we have the option to
move when problems or opportunities require it.&lt;&#x2F;p&gt;
&lt;p&gt;Lock-in is a good short-term strategy, but is rarely beneficial long-term.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🎯 Why do we need some level of control?</title>
        <published>2024-07-29T00:00:00+00:00</published>
        <updated>2024-07-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0009-why-do-we-need-some-level-of-control/"/>
        <id>https://bec-systems.com/blog/0009-why-do-we-need-some-level-of-control/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0009-why-do-we-need-some-level-of-control/">&lt;p&gt;In today’s connected systems, some level of control of your Platform is needed.&lt;&#x2F;p&gt;
&lt;p&gt;Security problems needed fixed.&lt;&#x2F;p&gt;
&lt;p&gt;Problems needed debugged.&lt;&#x2F;p&gt;
&lt;p&gt;Problematic subsystems need swapped out.&lt;&#x2F;p&gt;
&lt;p&gt;Suppliers go out of business.&lt;&#x2F;p&gt;
&lt;p&gt;Parts go obsolete.&lt;&#x2F;p&gt;
&lt;p&gt;New customers require new features.&lt;&#x2F;p&gt;
&lt;p&gt;We may want to leverage new technologies.&lt;&#x2F;p&gt;
&lt;p&gt;New Open Source projects become available.&lt;&#x2F;p&gt;
&lt;p&gt;We obviously can’t control every detail, but we at least need enough control to
adapt and respond to change or the unexpected.&lt;&#x2F;p&gt;
&lt;p&gt;Control is required because we can’t predict everything up front.&lt;&#x2F;p&gt;
&lt;p&gt;With complex systems, this is more true than ever.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏁 The long game</title>
        <published>2024-07-26T00:00:00+00:00</published>
        <updated>2024-07-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0008-the-long-game/"/>
        <id>https://bec-systems.com/blog/0008-the-long-game/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0008-the-long-game/">&lt;p&gt;Platforms are long games.&lt;&#x2F;p&gt;
&lt;p&gt;If you are building a one-off consumer product that will not be maintained,
improved, or ever change, then you probably don’t need a platform.&lt;&#x2F;p&gt;
&lt;p&gt;However, if you are building an long-lived industrial product that will be
maintained, or a series of related products, then it gets very expensive to
start over every time.&lt;&#x2F;p&gt;
&lt;p&gt;To effectively maintain multiple unrelated products, or a system that that is
difficult to update, improve, test, and deploy is a recipe for cripling
technical debt.&lt;&#x2F;p&gt;
&lt;p&gt;The expectation today is things will improve over time, because software can be
updated. It is not really optional any more.&lt;&#x2F;p&gt;
&lt;p&gt;And with the complexity of systems today, the odds you’ll get perfect on the
first release are near zero.&lt;&#x2F;p&gt;
&lt;p&gt;Build for the long game.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>♾️ It&#x27;s about not starting over every time</title>
        <published>2024-07-25T00:00:00+00:00</published>
        <updated>2024-07-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0007-its-about-not-starting-over/"/>
        <id>https://bec-systems.com/blog/0007-its-about-not-starting-over/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0007-its-about-not-starting-over/">&lt;p&gt;Platforms are about reuse.&lt;&#x2F;p&gt;
&lt;p&gt;Not starting over on every new product.&lt;&#x2F;p&gt;
&lt;p&gt;Leveraging what you have done before is one way to scale your efforts.&lt;&#x2F;p&gt;
&lt;p&gt;Reuse takes practice and experience to get it right.&lt;&#x2F;p&gt;
&lt;p&gt;Effective platforms are an art.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🌐 Complex Systems, Simple Platforms</title>
        <published>2024-07-24T00:00:00+00:00</published>
        <updated>2024-07-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0006-complex-systems-simple-platforms/"/>
        <id>https://bec-systems.com/blog/0006-complex-systems-simple-platforms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0006-complex-systems-simple-platforms/">&lt;p&gt;The word “simple” in the context of modern systems may seem like an oxymoron.&lt;&#x2F;p&gt;
&lt;p&gt;We can’t deny that modern systems are complex – they need to be to do the
things they do.&lt;&#x2F;p&gt;
&lt;p&gt;The role of a Platform is to reign in this complexity and create a way to
effectively manage and interact with the system.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms narrow our focus to the problem we are solving.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms decouple us from being too entangled or dependent on any one technology
or system.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms are the abstraction on top of complex systems that make them workable.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🔹 Simplicity</title>
        <published>2024-07-22T00:00:00+00:00</published>
        <updated>2024-07-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0005-simplicity/"/>
        <id>https://bec-systems.com/blog/0005-simplicity/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0005-simplicity/">&lt;p&gt;What is the role of simplicity in your platform?&lt;&#x2F;p&gt;
&lt;p&gt;Simplicity makes it easier for people to use your platform.&lt;&#x2F;p&gt;
&lt;p&gt;Simplicity helps ensure maintainability.&lt;&#x2F;p&gt;
&lt;p&gt;Simplicity moves us toward reliable and secure platforms.&lt;&#x2F;p&gt;
&lt;p&gt;Simple is not easy, actually it’s &lt;strong&gt;much&lt;&#x2F;strong&gt; harder than complex. But platforms
are a long game.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>🏢 What is your Platform?</title>
        <published>2024-07-18T00:00:00+00:00</published>
        <updated>2024-07-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0004-what-is-a-platform/"/>
        <id>https://bec-systems.com/blog/0004-what-is-a-platform/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0004-what-is-a-platform/">&lt;p&gt;What is a Platform?&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways to look at this. Some might think of AWS, GCP, iOS, Android,
etc.&lt;&#x2F;p&gt;
&lt;p&gt;These are certainly platforms, but they are not &lt;em&gt;your&lt;&#x2F;em&gt; platform.&lt;&#x2F;p&gt;
&lt;p&gt;Your platform is the collection of technology, tools, and processes you use to
do what you do.&lt;&#x2F;p&gt;
&lt;p&gt;This may be building products, delivering services, developing people, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>✨ The Beauty of Constraints</title>
        <published>2024-07-17T00:00:00+00:00</published>
        <updated>2024-07-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0003-beauty-of-constraints/"/>
        <id>https://bec-systems.com/blog/0003-beauty-of-constraints/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0003-beauty-of-constraints/">&lt;p&gt;Constraints are what guide us to good solutions.&lt;&#x2F;p&gt;
&lt;p&gt;Software that is simple enough that average developers can actually understand
it.&lt;&#x2F;p&gt;
&lt;p&gt;A user interface that is intuitive.&lt;&#x2F;p&gt;
&lt;p&gt;A system we can deploy without a dedicated SRE team.&lt;&#x2F;p&gt;
&lt;p&gt;Hardware created with open tools that anyone in our organization can maintain.&lt;&#x2F;p&gt;
&lt;p&gt;An architecture that can scale in unforeseen directions.&lt;&#x2F;p&gt;
&lt;p&gt;Flexible core data structures that rarely change.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Platforms are all about constraints.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>😱 The tragedy of no constraints</title>
        <published>2024-07-16T00:00:00+00:00</published>
        <updated>2024-07-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0002-tragedy-of-no-constraints/"/>
        <id>https://bec-systems.com/blog/0002-tragedy-of-no-constraints/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0002-tragedy-of-no-constraints/">&lt;p&gt;We never have enough time, resources, funding, CPU, storage, etc.&lt;&#x2F;p&gt;
&lt;p&gt;However, think what would happen if we had infinite resources.&lt;&#x2F;p&gt;
&lt;p&gt;We would never get started because we have forever to do it.&lt;&#x2F;p&gt;
&lt;p&gt;With unlimitted resources, we tend to make a mess and get sloppy.&lt;&#x2F;p&gt;
&lt;p&gt;Getting everything we want leads to bloat and lethargy.&lt;&#x2F;p&gt;
&lt;p&gt;Platforms are a long game, and but no contraints encourages short-term thinking.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>👋 Introduction</title>
        <published>2024-07-15T00:00:00+00:00</published>
        <updated>2024-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/blog/0001-intro/"/>
        <id>https://bec-systems.com/blog/0001-intro/</id>
        
        <content type="html" xml:base="https://bec-systems.com/blog/0001-intro/">&lt;p&gt;Product development is hard.&lt;&#x2F;p&gt;
&lt;p&gt;Technical debt tends to accrue at a frightening pace.&lt;&#x2F;p&gt;
&lt;p&gt;A “Platform” approach helps you reign in the chaos.&lt;&#x2F;p&gt;
&lt;p&gt;And provides a framework to reuse, scale, and leverage your efforts.&lt;&#x2F;p&gt;
&lt;p&gt;This newsletter provides tips to help you in the journey to
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;014&#x2F;&quot;&gt;“Own your Platform.”&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Ability to Improve</title>
        <published>2024-03-05T00:00:00+00:00</published>
        <updated>2024-03-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2267/the-ability-to-improve/"/>
        <id>https://bec-systems.com/2267/the-ability-to-improve/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2267/the-ability-to-improve/">&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-6.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;em&gt;(while this article contains many general ideas, it is written from the perspective of product development.)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;If you don’t continually improve, you soon lose the ability to do so …&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This thought came after an associate described a company that is struggling to manufacture one of their products:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;They have been making a product since way back in the last century. EOL (end-of-life) is catching up with them. The circuit is really hairy analog stuff with ridiculously high precision. Pots everywhere to get it dialed in. But their voltage regulator is drifting in value significantly, whereas the old parts are rock steady.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;How do we get into situations like this, and how can they be avoided?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-few-more-examples&quot;&gt;A few more examples&lt;&#x2F;h2&gt;
&lt;p&gt;Below are a few more examples of situations that are very difficult to deal with in the lifecycle of a product:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A part becomes obsolete in a printed circuit design, and no one knows how to use the CAD system it was designed in. Rather than updating to an &lt;a href=&quot;&#x2F;1670&#x2F;reflections-on-kicad-and-eda-tools&#x2F;&quot;&gt;open&#x2F;modern CAD system&lt;&#x2F;a&gt; years ago at a relaxed pace, exorbitant efforts are now spent trying to track down a few more parts or find a replacement. When this fails, it is now a frantic crash-and-burn project to revise the design with no time for testing and verification.&lt;&#x2F;li&gt;
&lt;li&gt;A serious security problem is found in a product, but the software build system has fallen into disrepair and no one knows how to set it up, and it will not run on current operating systems.&lt;&#x2F;li&gt;
&lt;li&gt;A new Linux kernel driver is needed to support a new USB peripheral, but the kernel we are shipping is 7 years old, and the SOC&#x2F;SOM vendor has not provided any updates. Updating to the latest kernel would take months. Backporting the new driver is nearly impossible due to the many changes in the kernel and its subsystems.&lt;&#x2F;li&gt;
&lt;li&gt;Manufacturing was outsourced to another country years ago. Then COVID happened and the manufacturer shut down for an extended time. No one knows where the design files are or how to build the product to move it to another manufacturer.&lt;&#x2F;li&gt;
&lt;li&gt;The manufacturing process for a complex product has been the same for years. No one knows why things are done the way they are, but are afraid to change anything for fear that problems may crop up.&lt;&#x2F;li&gt;
&lt;li&gt;A code base has not been refactored as it grew and no tests were written. Adding new functionality is very difficult and usually causes bugs in unrelated areas, requiring an exorbitant amount of manual testing with each release.&lt;&#x2F;li&gt;
&lt;li&gt;An application does not have a cohesive architecture. Global variables and unrestrained function calls between various subsystems are common. As time goes on, the application becomes less and less stable. Fixing one bug often causes another. All developer resources are consumed in a circle of support, continuous bug fixing, and damage control.&lt;&#x2F;li&gt;
&lt;li&gt;A new customer is interested in purchasing a product, but it is missing a critical feature. The original development was contracted to an outside development firm, and there is no knowledge in-house on how to modify the software. The managers at the company are scrambling to find someone who can figure out how to make the changes needed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;Technical debt&lt;&#x2F;em&gt; is another term to describe systems that are not adequately maintained – eventually, it takes so much effort just to keep things going that no time is left for improvements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;maintaining-systems&quot;&gt;Maintaining Systems&lt;&#x2F;h2&gt;
&lt;p&gt;How do you maintain the ability to react to changes, security problems, part shortages, and feature requests? How can you add value to your products over time? Maintaining systems (both hardware and software) is what keeps them malleable and flexible. If you don’t maintain stuff, then it soon becomes brittle and harder and harder to change. Modern systems are not ship-it-and-you-’re-done, but rather more similar to a living organism. If it is not maintained, it is dying.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The only way to make sure you &lt;em&gt;can&lt;&#x2F;em&gt; maintain something is to maintain it.&lt;&#x2F;strong&gt; Make it better. Replace a part with a cheaper&#x2F;better one. Improve something. Add a feature. Make it faster. Streamline and simplify manufacturing. If we don’t continually improve, then it becomes difficult to do anything without starting over. It is much easier to absorb a series of small costs over time than a large expense all at once. Small changes over time allow us to improve our processes. If we are not under pressure and something goes wrong, then we simply revert to the previous version or write tests to keep it from happening again.&lt;&#x2F;p&gt;
&lt;p&gt;This does not have to be hard, but it does require an investment in methodology and workflow. It requires a commitment to open tools, automation, and testing. It requires process – not the type that results in stifling bureaucracy but rather improves efficiency through automation and transparency.&lt;&#x2F;p&gt;
&lt;p&gt;There are several concerns related to change including return on investment (ROI), quality, and efficiency.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-roi-objection&quot;&gt;The ROI Objection&lt;&#x2F;h2&gt;
&lt;p&gt;There are two financial mindsets:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;View R&amp;amp;D as a one-time capital expense where you design something, lock it down, and then try to extract as much value as possible – the “minimizing costs” mindset.&lt;&#x2F;li&gt;
&lt;li&gt;View R&amp;amp;D as an ongoing operating expense, improve things over time, and continually increase value – the “maximizing value” mindset.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first is easier to measure and forecast. Financial people like and understand this model. The second requires intuition and vision. It involves some risk. As your processes become more efficient, the value you get from an improvement begins to outweigh the costs of making the change. Over time, these improvements have a compounding effect.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;01&#x2F;image-1.png&quot; alt=&quot;&quot; style=&quot;width:680px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;It depends if you are playing the short or long-term game …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-quality-objection&quot;&gt;The Quality Objection&lt;&#x2F;h2&gt;
&lt;p&gt;Stability and Quality is always a concern with any change in a system. With changes, mistakes will be made – especially early on. When this happens, there is an opportunity to learn and proactively improve the testing and verification process for next time, or reactively place blame, lock things down even harder, and remove responsibility. When someone introduces a bug, the question should be: “Did you create a test so it does not happen again?” If no mistakes are being made, not much is likely being done. The upside of growth and improvement should far exceed the costs associated with the occasional mistakes made in the course of changes. Done right, quality should follow the same value curve as the value shown in the graph above. The key is to not get discouraged by an initial drop in quality and focus on improving the processes, not minimizing or restricting change and responsibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-efficiency-objection&quot;&gt;The Efficiency Objection&lt;&#x2F;h2&gt;
&lt;p&gt;Efficiency is always a concern, and again there are two schools of thought:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It is more efficient if we just do things the way we’ve always done them, not risk change, and get what we can out of our investment. Change brings risk.&lt;&#x2F;li&gt;
&lt;li&gt;Efficiency can always improve, bringing lower costs and more value.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Again, the key is to be patient with the initial declines and persevere until you get to the point where efficiency is increasing and the cost and value lines cross.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;case-studies&quot;&gt;Case Studies&lt;&#x2F;h2&gt;
&lt;p&gt;Tesla is an interesting case study on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;insideevs.com&#x2F;news&#x2F;631485&#x2F;tesla-model-s-constant-improvements-chief-designer-says&#x2F;&quot;&gt;continuous improvement&lt;&#x2F;a&gt;. From a design and manufacturing perspective, their accomplishments are notable. There is always a better way to design or manufacture something.&lt;&#x2F;p&gt;
&lt;p&gt;Google’s &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sre.google&#x2F;sre-book&#x2F;postmortem-culture&quot;&gt;blameless postmortem&lt;&#x2F;a&gt; practice enables proactive improvements for the future instead of reactively placing blame for the past.&lt;&#x2F;p&gt;
&lt;p&gt;Amazon’s &lt;em&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;blogs&#x2F;enterprise-strategy&#x2F;enterprise-devops-why-you-should-run-what-you-build&#x2F;&quot;&gt;“You build it, you run it”&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; philosophy allows people who know the most about the system to improve how it is run instead of going through endless rounds with gatekeepers who don’t understand the system.&lt;&#x2F;p&gt;
&lt;p&gt;Toyota’s implementation of “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&quot;&gt;kaizen&lt;&#x2F;a&gt;” has produced &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.topspeed.com&#x2F;the-secrets-behind-toyotas-bullet-proof-reliability&#x2F;&quot;&gt;excellent results&lt;&#x2F;a&gt;. Kaizen is a concept referring to business activities that continuously improve all functions and involve all employees from the CEO to the assembly line workers.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These practices are used at large successful companies, but in concept, they are simple and can be applied at any scale.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-irony-of-kaizen&quot;&gt;The Irony of Kaizen&lt;&#x2F;h2&gt;
&lt;p&gt;We can develop products with the thought – we are going to get this perfect and then go into production. Logically it would seem that if we expect to make improvements after it is in production, then we must be starting with an inferior product with flaws. However, Toyota has proved the opposite. Even when a model is first introduced, their quality is likely better than the average in the automobile industry. Kaizen does not mean we slop something together of inferior quality, but rather we do the best we can but have the humility to realize it can always be better. Kaizen is not limited to the assembly line, but all aspects including design, prototyping, quality control, testing, etc. If all of these processes are continually getting better, then the first item produced will also be better.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;requirements-for-improvement&quot;&gt;Requirements for Improvement&lt;&#x2F;h2&gt;
&lt;p&gt;Every person and every organization is different, so there is no one-size-fits-all recipe that will always work. But there are several ingredients that are generally beneficial including:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Metrics&lt;&#x2F;li&gt;
&lt;li&gt;Testing&lt;&#x2F;li&gt;
&lt;li&gt;Openness&lt;&#x2F;li&gt;
&lt;li&gt;Simplicity&lt;&#x2F;li&gt;
&lt;li&gt;Leveraging outside improvements&lt;&#x2F;li&gt;
&lt;li&gt;Iterate faster&lt;&#x2F;li&gt;
&lt;li&gt;Owning your platform&lt;&#x2F;li&gt;
&lt;li&gt;The right people&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;metrics&quot;&gt;Metrics&lt;&#x2F;h2&gt;
&lt;p&gt;Not all change is an improvement – change for the sake of change is just churn and generally negative. You have to be able to measure something to know if things are improving or not. Improvement is very difficult without some metrics, because we are then just guessing and going off our intuition, and human intuition is often distorted by emotion, social pressures, and a host of other distractions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h2&gt;
&lt;p&gt;Testing is trendy today and many talk about it, but fewer individuals and teams have the discipline to implement testing consistently. If you are not confident enough to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;discourse-living-on-the-edge&#x2F;1222&quot;&gt;deploy new software to production after your tests pass&lt;&#x2F;a&gt; without doing some manual checking, then you possibly need better tests. Automated end-to-end and performance testing is critical. Consider the following statement about SQLite:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reliability and robustness of SQLite is achieved in part by thorough and careful testing.&lt;&#x2F;p&gt;
&lt;p&gt;As of version 3.42.0 (2023-05-16), the SQLite library consists of approximately 155.8 KSLOC of C code. (KSLOC means thousands of “Source Lines Of Code” or, in other words, lines of code excluding blank lines and comments.) By comparison, the project has 590 times as much test code and test scripts - 92053.1 KSLOC.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;testing.html&quot;&gt;https:&#x2F;&#x2F;www.sqlite.org&#x2F;testing.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Most of SQLite’s tests are not open-source. This is the real IP of SQLite.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openness&quot;&gt;Openness&lt;&#x2F;h2&gt;
&lt;p&gt;Openness is another necessary ingredient for improvement. This takes many forms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Open access to tools, design files, and source code. Open-source software and tools are preferred when available.&lt;&#x2F;li&gt;
&lt;li&gt;Good documentation is available to all involved.&lt;&#x2F;li&gt;
&lt;li&gt;Work being done is in the open and can be reviewed by anyone at any time. Pull requests are created when work starts to provide visibility into work being done rather than when the work is finished. Transparency is a powerful ingredient for quality.&lt;&#x2F;li&gt;
&lt;li&gt;Metrics, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ted.com&#x2F;talks&#x2F;ricardo_semler_how_to_run_a_company_with_almost_no_rules&quot;&gt;including financial information&lt;&#x2F;a&gt; and customer feedback, are accessible to the team.&lt;&#x2F;li&gt;
&lt;li&gt;Anyone on the team to allowed and encouraged to fix or improve anything. There are no “turf battles” where only certain people are allowed to do certain things. Within practical limits, anyone can do any work, but the process (transparency and testing) ensures that substandard work will not be automatically used.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above does not mean everything is open-source to the world, but rather those involved with the product – a team, organization, company, customers, partners, etc. We can learn a lot from the success of open-source projects and their associated culture and methodologies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simplicity&quot;&gt;Simplicity&lt;&#x2F;h2&gt;
&lt;p&gt;As the complexity of systems continues to increase, we need to also be aware that humans interacting with these systems are finite – we can only handle so much complexity. Thus, efforts need to be made to simplify where possible. We often hear the phrase: “keep it simple!” But, from whose perspective? Design, Manufacturing, Users, Service, Ops, Support, Sales, Financial, CEO, etc. If we look at how much time these various groups interact with the product, we can arrange them in an inverted pyramid:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-5.png&quot; alt=&quot;&quot; style=&quot;width:571px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The &lt;em&gt;CEO&lt;&#x2F;em&gt; is only one person and hopefully, there are many &lt;em&gt;Users&lt;&#x2F;em&gt;, so if we can simplify things for the &lt;em&gt;Users&lt;&#x2F;em&gt;, that will probably provide more benefits to the product than simplifying things for the &lt;em&gt;CEO&lt;&#x2F;em&gt;. Likewise, if &lt;em&gt;Design&lt;&#x2F;em&gt; can spend a little more time making &lt;em&gt;Manufacturing&lt;&#x2F;em&gt; and &lt;em&gt;Support&lt;&#x2F;em&gt; simpler, that is probably a good investment.&lt;&#x2F;p&gt;
&lt;p&gt;Simplifying a system’s architecture often provides the biggest wins. This can take the form of common data structures, how data is structured, how data is communicated and synchronized, lifecycle management, etc. A simplification at this level has the potential to improve the entire system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;faster-iterations&quot;&gt;Faster Iterations&lt;&#x2F;h2&gt;
&lt;p&gt;The most efficient way for humans to design complex systems is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bradfordembedded.com&#x2F;2012&#x2F;03&#x2F;iterate-hardware-like-software&quot;&gt;through iteration&lt;&#x2F;a&gt;. Some call this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;platform-takes-the-pain-corecursive-podcast&#x2F;1212&#x2F;3?u=cbrake&quot;&gt;failing fast&lt;&#x2F;a&gt;. The faster you can design&#x2F;develop, test, get feedback, and repeat, the more likely you will be successful.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-1.png&quot; alt=&quot;&quot; style=&quot;width:559px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There is certainly a place for some up-front planning, but you don’t want to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2001&#x2F;04&#x2F;21&#x2F;dont-let-architecture-astronauts-scare-you&#x2F;&quot;&gt;get stuck there&lt;&#x2F;a&gt;. Build a minimal &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;yagni-you-aint-gonna-need-it-and-cake-models&#x2F;1217&quot;&gt;slice of your product&lt;&#x2F;a&gt; as soon as possible, even if it only has a few features. This can even be done with hardware – put down only the bare minimum parts on the PCB and build something. The rest can be added later. If it takes too long to build a PCB prototype, find ways to speed it up, or switch to another vendor. Automation and process is very important for fast iterations. CI (continuous integration) tells you quickly if your code fails tests. CD (continuous delivery) continually builds and deploys your work so that it can be tested in the complete system and evaluated by others. CAD and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&#x2F;gitplm&quot;&gt;PLM automation&lt;&#x2F;a&gt; allows you to quickly package, track, and build new versions of PCBs.&lt;&#x2F;p&gt;
&lt;p&gt;A focus on iteration compensates for our many human weaknesses. It reveals our blind spots. It improves teamwork and project transparency. It helps avoid the scenario where the lone genius works for three months behind closed doors while the rest of the team is largely stalled. It ensures we are building what the customer actually needs. It encourages automation to avoid the tedium of manual testing and releases. It accelerates learning. Above all, it improves the efficiency of the entire process. It ensures we can quickly make changes and release them when needed, with confidence.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;owning-your-platform&quot;&gt;Owning Your Platform&lt;&#x2F;h2&gt;
&lt;p&gt;Owning your platform means you “own” and take responsibility for key parts of whatever it takes to build and maintain your products. It might be a printed circuit design, a build system, an application architecture, automation, infrastructure, process, etc. Owning your platform likewise is an investment for the future. It gives you more control and the ability to improve things. You are not locked into what another company provides at one snapshot in time. Certainly, there are limits to this and we cannot create an entire system from scratch so we all must use software and components that other companies create. However, we can build a system that has flexibility so that we can easily swap out one component for another. We can understand it well enough to test it. We can manage the build systems so that if something needs to be fixed or updated, we can do that. We build our device software when possible instead of relying on binary images that we can’t control. We are not afraid of developing our own automation and process software instead of relying entirely on outside vendors. Perhaps the most important thing is to own the integration points. This might include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Top-level PCB (printed circuit board) designs (we can change electronic components and submodules as needed)&lt;&#x2F;li&gt;
&lt;li&gt;Software build systems (we can add, remove, and update software components)&lt;&#x2F;li&gt;
&lt;li&gt;PLM (project lifecycle management) (we write our own or use a system that can be easily extended through programming to meet our needs)&lt;&#x2F;li&gt;
&lt;li&gt;Core application architecture (can be adapted to specifically meet our needs)&lt;&#x2F;li&gt;
&lt;li&gt;Hosting (we can run our own servers or move applications between hosting providers as needs change)&lt;&#x2F;li&gt;
&lt;li&gt;CI&#x2F;CD (can be adapted to any task&#x2F;technology)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Integration is the most difficult (but also the most valuable) part of product development, so it is tempting to outsource integration. But this often locks you into one vendor and does not give you the flexibility to scale to higher volumes or additional products, as this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;why-were-leaving-the-cloud&#x2F;697&quot;&gt;running commentary&lt;&#x2F;a&gt; illustrates.&lt;&#x2F;p&gt;
&lt;p&gt;Ideally, you can reuse parts of your platform across many products, thus compounding your efforts over time. Even if your design files and source code are open-source, owning your platform (which includes so much more than design files) is what gives you the ability to efficiently design, test, maintain, and produce something. This is the hard part. If you are moving fast, a static snapshot of your product design at any point in time is of marginal value to competitors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leveraging-outside-improvements&quot;&gt;Leveraging Outside Improvements&lt;&#x2F;h2&gt;
&lt;p&gt;Leveraging outside improvements is another important activity. This can include upgrading to a new open-source software component, designing in a new integrated circuit, etc. It is easy to get stuck in the mindset that the “old” was “better.” In some aspects of life, this may be true, but with technology, things are generally getting better. Open-source software is generally more stable as time goes on due to better testing. Newer integrated circuits are more capable and lower cost. Many products today are largely an integration of many outside technologies, many of which are &lt;a href=&quot;&#x2F;2014&#x2F;why-open-source-for-product-development&#x2F;&quot;&gt;now open-source&lt;&#x2F;a&gt;. To improve, we must continually track and integrate these improvements. Developing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;024&#x2F;&quot;&gt;using the mainline&lt;&#x2F;a&gt; (upstream) branch of open-source projects is a good strategy that companies are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.toradex.com&#x2F;blog&#x2F;upstream-first-mainline-kernel-support-is-reality&quot;&gt;increasingly adopting&lt;&#x2F;a&gt;. Knowing &lt;a href=&quot;&#x2F;2084&#x2F;the-technology-trajectory&#x2F;&quot;&gt;when to adopt&lt;&#x2F;a&gt; new technology is a key skill.&lt;&#x2F;p&gt;
&lt;p&gt;If you use an outside development firm to develop parts of your product, it is critical that you receive a deliverable that is maintainable. Several suggestions for ensuring this include:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;run the project like an open-source project. All activity is transparent and is committed to Git often.&lt;&#x2F;li&gt;
&lt;li&gt;own the integration points and testing.&lt;&#x2F;li&gt;
&lt;li&gt;use small iterations when possible. This ensures you are engaged and what is being built is what you need.&lt;&#x2F;li&gt;
&lt;li&gt;use &lt;a href=&quot;&#x2F;1670&#x2F;reflections-on-kicad-and-eda-tools&#x2F;&quot;&gt;open tools&lt;&#x2F;a&gt;&#x2F;technology that everyone has easy access to where possible. Ensure that you can build or generate usable outputs from the design&#x2F;source files. Even if you don’t have the expertise to use the tools, there is a better chance you can find someone else who can.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;the-right-people&quot;&gt;The Right People&lt;&#x2F;h2&gt;
&lt;p&gt;There is a saying often used by hikers: “Leave it better than you found it.” If we are working on a section of code that does not have tests, do we write them? If a manufacturing problem is found, do we improve the process to try to prevent the problem in the future, or just write it off? Do we give more responsibility and opportunity to everyone involved to improve things, or do we let a few mistakes restrict responsibility to only a few people?&lt;&#x2F;p&gt;
&lt;p&gt;For this to all work, you have to have people with integrity – who are genuinely interested in improvement and not just gaming the metrics. You have to have people with the discipline to write tests, which goes above and beyond just getting the job done and the ticket closed.&lt;&#x2F;p&gt;
&lt;p&gt;This all applies personally too … do you want to improve how you use your time? Then measure how you spend your time and share these measurements with someone. Use one of the many tools available to help track your time. Create your own tooling and process, and then improve it. Look for better ways to do all this.&lt;&#x2F;p&gt;
&lt;p&gt;Fundamentally, people don’t usually change much, so if someone is not interested in improving themselves, they likely will not be interested in improving the organizations they are a part of and be a drag on the process. So perhaps the most fundamental thing to learn in an interview is not only past accomplishments, but also if the candidate still has that burning desire to learn and improve themselves. It is a frustrating situation when a person who is wired for improvement is part of an organization that is not, or vice-versa. Both types of people and organizations exist.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-changes-vs-large-changes&quot;&gt;Small Changes vs Large Changes&lt;&#x2F;h2&gt;
&lt;p&gt;We can make small or large changes. This might be the difference between an improvement vs. a pivot, slow and steady vs drama. The drama captures attention in the news – the new charismatic CEO brought in from the outside to shake things up. You typically don’t see great companies in the news, but you do see them in investment portfolios. In his book &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;article_topics&#x2F;articles&#x2F;good-to-great.html&quot;&gt;“Good to Great,”&lt;&#x2F;a&gt; Jim Collins studied several companies that produced exceptional results and concluded the following:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;We keep looking for change in the wrong places, asking the wrong questions, and making the wrong assumptions. There’s even a tendency to blame Wall Street for the “instant results” approach to change. But the companies that made the jump from good to great did so using Wall Street’s own tough metric of success: a sustained leap in their stock-market performance. Wall Street turns out to be just another myth—an excuse for not doing what really works. The data doesn’t lie.&lt;&#x2F;p&gt;
&lt;p&gt;Now picture a huge, heavy flywheel. It’s a massive, metal disk mounted horizontally on an axle. It’s about 100 feet in diameter, 10 feet thick, and it weighs about 25 tons. That flywheel is your company. Your job is to get that flywheel to move as fast as possible, because momentum—mass times velocity—is what will generate superior economic results over time.&lt;&#x2F;p&gt;
&lt;p&gt;Right now, the flywheel is at a standstill. To get it moving, you make a tremendous effort. You push with all your might, and finally you get the flywheel to inch forward. After two or three days of sustained effort, you get the flywheel to complete one entire turn. You keep pushing, and the flywheel begins to move a bit faster. It takes a lot of work, but at last the flywheel makes a second rotation. You keep pushing steadily. It makes three turns, four turns, five, six. With each turn, it moves faster, and then—at some point, you can’’t say exactly when—you break through. The momentum of the heavy wheel kicks in your favor. It spins faster and faster, with its own weight propelling it. You aren’t pushing any harder, but the flywheel is accelerating, its momentum building, its speed increasing.&lt;&#x2F;p&gt;
&lt;p&gt;This is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;the-flywheel.html&quot;&gt;Flywheel Effect&lt;&#x2F;a&gt;. It’s what it feels like when you’re inside a company that makes the transition from good to great. Take Kroger, for example. How do you get a company with more than 50,000 people to embrace a new strategy that will eventually change every aspect of every grocery store? You don’t. At least not with one big change program.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, you put your shoulder to the flywheel. That’s what Jim Herring, the leader who initiated the transformation of Kroger, told us. He stayed away from change programs and motivational stunts. He and his team began turning the flywheel gradually, consistently—building tangible evidence that their plans made sense and would deliver results.&lt;&#x2F;p&gt;
&lt;p&gt;“We presented what we were doing in such a way that people saw our accomplishments,”Herring says. “We tried to bring our plans to successful conclusions step by step, so that the mass of people would gain confidence from the successes, not just the words.”&lt;&#x2F;p&gt;
&lt;p&gt;Think about it for one minute. Why do most overhyped change programs ultimately fail? Because they lack accountability, they fail to achieve credibility, and they have no authenticity. It’s the opposite of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;the-flywheel.html&quot;&gt;Flywheel Effect&lt;&#x2F;a&gt;; it’s the Doom Loop.&lt;&#x2F;p&gt;
&lt;p&gt;Companies that fall into the Doom Loop genuinely want to effect change—but they lack the quiet discipline that produces the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;the-flywheel.html&quot;&gt;Flywheel Effect&lt;&#x2F;a&gt;. Instead, they launch change programs with huge fanfare, hoping to “enlist the troops.” They start down one path, only to change direction. After years of lurching back and forth, these companies discover that they’ve failed to build any sustained momentum. Instead of turning the flywheel, they’ve fallen into a Doom Loop: Disappointing results lead to reaction without understanding, which leads to a new direction—a new leader, a new program—which leads to no momentum, which leads to disappointing results. It’s a steady, downward spiral. Those who have experienced a Doom Loop know how it drains the spirit right out of a company.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;article_topics&#x2F;articles&#x2F;good-to-great.html&quot;&gt;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;article_topics&#x2F;articles&#x2F;good-to-great.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Change is easiest to implement and absorb if it is incremental and not a drastic overhaul. Incremental change allows you to measure, adjust, and backtrack if needed. Incremental improvements can be implemented by anyone without permission and can then be evaluated and improved by others.&lt;&#x2F;p&gt;
&lt;p&gt;It is also important to understand the difference between foundational truths&#x2F;values (things you should not quickly change) and inefficiencies that and ripe for improvement. The foundational principles of your business provide stability and need to be understood and valued.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Do you want to be able to respond quickly to unexpected opportunities or issues that come up? The solution is simple – practice doing so now. If you regularly practice on the little things that by themselves may not really be worth the time to do, several things will happen:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;you will be ready and practiced to make critical changes that will make a big difference such as fixing a critical security problem, responding to supply chain shortages, or making a change necessary to land a big sale.&lt;&#x2F;li&gt;
&lt;li&gt;the compounding effect of small improvements will eventually provide a sizable return in the future.&lt;&#x2F;li&gt;
&lt;li&gt;each small improvement is a small push on the flywheel of momentum. This adds positive energy to your organization and this momentum helps carry you through difficult times.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A culture of improvement is a long-term game. There will be some up-front pain as you develop your processes, but this is much easier than the long-term pain of accumulated technical debt which cripples your ability to do anything. You can compound the value from improvements or the cost of technical debt – take your choice.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Think Horses, not Zebras (Part 2)</title>
        <published>2024-03-01T00:00:00+00:00</published>
        <updated>2024-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2233/think-horses-not-zebras-part-2/"/>
        <id>https://bec-systems.com/2233/think-horses-not-zebras-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2233/think-horses-not-zebras-part-2/">&lt;p&gt;There is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&quot;&gt;popular quote&lt;&#x2F;a&gt; in medical circles:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you hear hoofbeats, think of horses, not zebras. — Dr. Theodore Woodward&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I recently &lt;a href=&quot;&#x2F;2138&#x2F;think-horses-not-zebras&#x2F;&quot;&gt;posted several debugging experiences&lt;&#x2F;a&gt; where it was beneficial to examine simple scenarios before complex ones. Below are a few more …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nvme-slot-not-working&quot;&gt;NVMe slot not working&lt;&#x2F;h2&gt;
&lt;p&gt;An NVMe slot is fairly simple – it has a clock and one to four PCIe lanes. However, in a recent new hardware design, the slot was not working. We reviewed the kernel boot logs, scoped the clock signals, etc. We did notice the clock amplitude was lower than other designs (see below). The initial suspect was signal integrity as the PCIe data lines run at very high speeds, so we reviewed the routing, board stackup, impedance calculations, etc. Eventually, I compared the PCIe connector pinout to another design and it appeared that the RX and TX data signals were swapped. Sometimes RX vs TX (receive vs transmit) can be a little confusing based on which perspective the signals are referenced to (the host system or the target device). In the case of PCIe, it appears the signals are all named from the perspective of the host. After modifying to swap the RX and TX signals, the NVMe slot worked fine, even though the modification wires drastically violated signal integrity and impedance requirements. PCIe must be a fairly robust transport!&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-10.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-11.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;pcie-clock-amplitude&quot;&gt;PCIe clock amplitude&lt;&#x2F;h2&gt;
&lt;p&gt;While verifying the hardware of a design, we noticed that the PCIe clock was at a lower amplitude than the specification required:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-7.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;What we were measuring:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-8.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The Vcross was about 170mV, and the spec required it to be between 250 and 500mV. To verify our measurement technique, we measured the PCIe clock on another system and it it looked correct. The default output of the clock chip should have given us the correct amplitude. The clock chip was connected via an I2C bus, so we read back the registers to make sure they were set to the defaults. We then set the amplitude to the maximum the chip would output, and it still was not within range. Finally, we noticed the following in the datasheet:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-9.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Sure enough, we had terminations resistors for these signals on the PCB. After the resistors were removed, the clock amplitude was correct.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cellular-connection-problems&quot;&gt;Cellular connection problems&lt;&#x2F;h2&gt;
&lt;p&gt;Cellular IoT systems can be tricky to troubleshoot. They are often installed in harsh environments (rain, cold, hot, damp, caustic sewer gasses, etc.). Occasionally a modem goes bad and connections fail. In one recent case, we replaced a modem and it still would not connect. The antenna, cable, and connections were the next suspect. After spending considerable time swapping components and not making any progress, I reviewed the configuration and noticed the APN was not set. After setting the cellular APN, it worked.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zephyr-nanopb-build-error&quot;&gt;Zephyr Nanopb build error&lt;&#x2F;h2&gt;
&lt;p&gt;We recently updated the version of Zephyr we were using in a project. In the process, a protobuf generation process broke and another developer found a solution – nanopb was now an optional dependency that needed to be activated. However, the build still failed in my workspace. We discussed diffing our build workspace, but in the back of my mind, I was thinking – there has to be a simple reason. While reading the documentation, it occurred to me to check the &lt;code&gt;west&lt;&#x2F;code&gt; version – sure enough, I was running 1.0 and the latest was 1.2. After updating, it worked.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-can-we-learn&quot;&gt;What can we learn?&lt;&#x2F;h2&gt;
&lt;p&gt;Again, in the above cases, the initial assumptions were more complex than the actual problem. Suggestions from the &lt;a href=&quot;&#x2F;2138&#x2F;think-horses-not-zebras&#x2F;&quot;&gt;previous article&lt;&#x2F;a&gt; are relevant here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Double-check connector and component pinouts.&lt;&#x2F;li&gt;
&lt;li&gt;Compare to working designs.&lt;&#x2F;li&gt;
&lt;li&gt;Re-read the entire datasheet carefully.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additional suggestions learned from these examples include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Verify the configuration of the system is correct, never assume it is.&lt;&#x2F;li&gt;
&lt;li&gt;Make sure you have the correct version of the tools installed (ideally your build system would check this for you).&lt;&#x2F;li&gt;
&lt;li&gt;Re-read documentation for tools and software components. This will often spark ideas on where to look for problems.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why Open Source for Product Development</title>
        <published>2023-12-01T00:00:00+00:00</published>
        <updated>2023-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2014/why-open-source-for-product-development/"/>
        <id>https://bec-systems.com/2014/why-open-source-for-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2014/why-open-source-for-product-development/">&lt;p&gt;(this topic is also discussed in a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;026&#x2F;&quot;&gt;podcast episode&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;One of the paradoxes in product development is Open Source. How can you personally or as a company benefit from participating in Open Source projects? Why should you share your great ideas and code? How can you build a business or a career by giving things away? How can an open-source project be a reliable supplier without contractual guarantees? Most successful technology companies today participate in open-source projects. Why do they do this?&lt;&#x2F;p&gt;
&lt;p&gt;Open source is difficult to fully understand and much has been said about it. There are many approaches to licensing and funding. Many question the equity and sustainability. Many get bogged down in ethical, moral, and political arguments. There are messy problems that don’t seem to have good answers. But we need to go deeper and examine the core issues of why companies are turning to open-source.&lt;&#x2F;p&gt;
&lt;p&gt;We will consider several product development perspectives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Our motivation is to produce something of &lt;strong&gt;value&lt;&#x2F;strong&gt; that society can use and benefit from.&lt;&#x2F;li&gt;
&lt;li&gt;Software technology is advancing at a rapid rate of &lt;strong&gt;change&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Technology in modern systems is increasingly &lt;strong&gt;complex&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;How can we maintain some level of &lt;strong&gt;control&lt;&#x2F;strong&gt; over the resources we use to ensure they will meet our needs?&lt;&#x2F;li&gt;
&lt;li&gt;And how does organizational &lt;strong&gt;culture&lt;&#x2F;strong&gt; impact our ability to deal with these issues and build modern systems?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2023&#x2F;10&#x2F;image.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;value&quot;&gt;Value&lt;&#x2F;h2&gt;
&lt;p&gt;The value of software is hard to quantify, and breakthroughs are difficult to predict. New software algorithms, methods, languages, and structures are sometimes much more effective than previous ones. It is these non-linear breakthroughs that we must leverage. Software is an unbounded sphere of opportunity, free from the constraints of physical locality, physical devices, duplication costs, and, in many cases, computing resources. Modern computers, even those we hold in our hands, are capable of running more software than we can write in multiple lifetimes and storing a lot of information. Systems that improve human efficiency and capability potentially add value and wealth to society. The best software can do more with simpler expressions and less effort. The best software can scale to larger problems. The best software is easier to maintain and thus the rate at which value is added over the long term increases. The best software is more reliable and can be easily deployed without worrying about it crashing or malfunctioning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complexity&quot;&gt;Complexity&lt;&#x2F;h2&gt;
&lt;p&gt;We should clarify our use of the term complexity – we are talking about inherent and necessary complexity, not artificial, human-created complexity (some call this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;No_Silver_Bullet&quot;&gt;accidental complexity&lt;&#x2F;a&gt;). The human body is incredibly complex, but this is necessary for it to do all the things it does. Modern microprocessors are complex, but they need to be in order to do the amount of processing they do. The Linux kernel is complex, but only because this is required. In modern systems, software is potentially orders of magnitude more complex than hardware. We might spend X hours designing the hardware and XY hours writing and maintaining the software over the lifecycle of the product. This is hard to comprehend because the hardware can be seen, but the software is largely invisible. Software is increasingly the driver of value in modern systems, whether the systems are products or processes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;change&quot;&gt;Change&lt;&#x2F;h2&gt;
&lt;p&gt;The development of hardware versus software requires a different mindset and process. With hardware, the effort is mostly in the initial development as we design, specify, and integrate the components needed. Once designed or qualified, a hardware component can be used for 5 or 10 years with very few changes. Its value is driven by minimizing variance (change), which is how we define hardware quality. Software systems are completely different – &lt;strong&gt;the inherent value in software is that it can be changed&lt;&#x2F;strong&gt; over a product lifecycle and its value subsequently increases, so the value in software comes from maximizing (instead of minimizing) changes. Software in a product may be updated hundreds or even thousands of times over its life. This is why it is so difficult for a company that is really good at hardware to also be good at software, or vice versa – a different culture and mindset are required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control&quot;&gt;Control&lt;&#x2F;h2&gt;
&lt;p&gt;How can we secure and have some level of control over the critical software components we need to build products? First, we should clarify the scope of the problem. Modern systems are increasingly assembled from hardware and software components we did not create ourselves. In a Linux-based system, there are many millions of lines of source code. The few thousands of lines of custom application code we might write for a product, which may represent many man-years of effort, are only a drop in the bucket compared to the rest of the software running in the system. However, it is easy to ignore the “rest” of the software, as it is largely invisible. How you manage the “rest” is critically important and perhaps the hardest part. And this “rest” is increasingly being supplied by open-source projects. Many engineers are good at creating things from scratch, but fewer are good at understanding, modifying, debugging, and managing software technology that others create. This skill is increasingly valuable.&lt;&#x2F;p&gt;
&lt;p&gt;Ideally, we would create everything we need and not be dependent on anyone else. However, we won’t get very far on our own if we need to create our own microprocessors, operating systems, programming languages, databases, and the myriad of other components needed to build systems. Likewise, these components by themselves are of little value unless they are combined into a larger system to do something useful. No one person, company, or even nation can build and maintain all the technology building blocks required to build modern systems. Human success is largely dependent on the degree to which we are able to work with others. The scope of the Linux kernel is beyond even the largest companies or governments. Even if an organization had the manpower, it would likely not have the culture required to pull off a project like the Linux kernel, the PostgreSQL database, or many other useful OSS projects. For smaller organizations, the capability to build even the most basic building blocks is often beyond our reach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;culture&quot;&gt;Culture&lt;&#x2F;h2&gt;
&lt;p&gt;Thus far we have established that to create &lt;strong&gt;value&lt;&#x2F;strong&gt; with modern systems, we must be able to build &lt;strong&gt;complex&lt;&#x2F;strong&gt; systems using software technology, much of which we did not create, and be able to &lt;strong&gt;change&lt;&#x2F;strong&gt; this software over time to deliver more value. In all this, we must have some level of &lt;strong&gt;control&lt;&#x2F;strong&gt; over this software. If there are problems, can we fix them? Can improvements be implemented and new features added? Secondly, can we influence development over time if we are not doing it ourselves? When we source software technology, there are many options, but let’s reduce it to two for the purpose of discussion:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Find a vendor with a proprietary software product. Initially, it fits our requirements – at least during the sales cycle. As changes&#x2F;fixes are needed in the future, this vendor is hired to provide these updates or we work around them.&lt;&#x2F;li&gt;
&lt;li&gt;Find an open-source software project. We may purchase support from a company supporting this project or we may make needed changes ourselves.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There are no doubt times when #1 is the best solution, but increasingly #2 is being chosen. Why is this?&lt;&#x2F;p&gt;
&lt;p&gt;Let’s again review the challenges with software development:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Obtaining the software we need (&lt;strong&gt;value&lt;&#x2F;strong&gt;), as we only have the resources to write a tiny fraction of it.&lt;&#x2F;li&gt;
&lt;li&gt;Making &lt;strong&gt;changes&lt;&#x2F;strong&gt; over the product lifecycle, as this is where value is added.&lt;&#x2F;li&gt;
&lt;li&gt;Having some level of &lt;strong&gt;control&lt;&#x2F;strong&gt; and influence over the software we use.&lt;&#x2F;li&gt;
&lt;li&gt;Managing the extreme &lt;strong&gt;complexity&lt;&#x2F;strong&gt; of modern systems.&lt;&#x2F;li&gt;
&lt;li&gt;Providing an environment and finding the people where software innovation can happen (&lt;strong&gt;culture&lt;&#x2F;strong&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As we review these challenges, we start to realize that the primary benefits of open-source software are cultural. Software innovation is not created with a manufacturing-type mentality but is more art than science – a process of discovery, experimentation, collaboration, inspiration, and simplification.  Developing great algorithms and code is a creative process that cannot be easily planned or scheduled, other than allocating the resources and time to work on it. The development of software innovations is not always predictable and cannot be forced. It requires the rare combination of the right people, the right environment, the right level of collaboration, and the freedom to experiment and innovate. All these conditions rarely exist inside corporations. Companies are realizing they cannot always hire the people needed or provide the environment for the level of innovation required. So the next best thing is to support open source projects where this innovation is happening. There are two ways to do this: time and funding.&lt;&#x2F;p&gt;
&lt;p&gt;Many authors of innovative software projects are driven by the craft itself, not wealth. Funding is necessary, but they are not working on a project to become rich – there are much easier ways to make money. They are driven by the intrinsic challenge, the joy of discovery, and the reward of building something useful. The first step in making sure an open-source project will be maintained and available in the future is to ensure that the authors have the funding they need. There will never be perfect equity in that authors will receive exact compensation proportional to the value they create, but this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;i-won-t-let-you-pay-me-for-my-open-source-d7cf4568&quot;&gt;matters little to most OSS authors&lt;&#x2F;a&gt;, and in reality, this is also the case with most developers employed by companies. Many developers are more than satisfied with earning a good living and having the freedom to work on whatever they choose. Most are generous and glad to see their work being used. However, there are cases where OSS authors do not receive funding comparable to what they could earn working elsewhere, so it would be&lt;strong&gt;wise for companies to audit all the OSS components they are dependent on and ensure that these projects are adequately funded&lt;&#x2F;strong&gt;. Contributing financially also makes it more likely the authors of the project will respond to the company’s needs, but we need to be careful that this process does not become restrictive to the point where the environment for innovation is destroyed.&lt;&#x2F;p&gt;
&lt;p&gt;Contributing time (code, documentation, support, feedback, etc.) to open-source projects is another way to help ensure a project will be useful and available to companies needing it. Contributing to the community around an open-source project is critical for the project’s health and is part of the flywheel of innovation. If someone is a valuable contributor, then they will also have some influence on the direction and priorities of the project. They will become skilled at understanding and using the project. They will also become better programmers, as they work with some of the best in the world, and are exposed to well-written software. Open source projects provide an environment for innovation that is often not possible inside a company, so having your engineers do some work in OSS projects provides them with an alternative environment to do software development.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-open-source-works&quot;&gt;Why Open-Source Works&lt;&#x2F;h2&gt;
&lt;p&gt;It is somewhat of a puzzle why the open-source environment works so well for software innovation. Transparency is a powerful tool for great work. When you do things in public, you do them better. In OSS projects, there are no barriers to working with the best people in the world. Freedom is likely another ingredient. When there is the latitude to experiment, it is more likely that new and better methods will be discovered. Formal software development methodologies are good at managing more predictable efforts to solve business problems, but they seem to be of less value in OSS projects at driving innovation. Each successful OSS project is different than the previous one and is a unique combination of various factors that cannot be easily replicated.&lt;&#x2F;p&gt;
&lt;p&gt;Many people still stumble at the fact that if my company contributes to an open-source project, we are helping our competitors. This is true. However, if we don’t participate in open-source projects, we likely won’t get to where we need to go. It may no longer be optional. Open source is not like walking into a discount store and picking something off the shelf at a tremendously good deal. It is not a one-time decision where we select something and are done. It is an ongoing process of continual change and improvement. And the better we are integrated into this process, the more we can leverage and use open source. Economic opportunity is not a fixed-sized pie, where we are all competing for the largest slice. With software, the duplication costs are near zero, so this is a perfect opportunity for economic growth or an overall increase in society’s wealth. We can work to grow the size of the pie, so everyone can have a larger slice.&lt;&#x2F;p&gt;
&lt;p&gt;Often in writing, the author learns and understands things he did not know before, and this essay is no exception. **The benefits of open source are not primarily in getting stuff for free or pooling resources in a socialist sense for the greater common good, but rather in providing an environment and connecting the right people for innovation to happen.**This dynamic has happened occasionally in the past inside companies such as &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;brian-kernighan-unix-c-awk-ampl-go-bell-labs-etc&#x2F;284&#x2F;7&quot;&gt;Bell Labs&lt;&#x2F;a&gt; and Lockheed Martin’s &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;lockheed-martin-skunkworks&#x2F;309&quot;&gt;Skunk Works&lt;&#x2F;a&gt;. But this environment is obviously difficult to replicate or more companies would do so. Even the largest and most successful technology companies, such as Google and Facebook, aggressively support and promote open source. At the time of this writing, Google employs over 27,000 engineers – why would they need open-source projects? With that number of developers, why can’t they create anything they would ever need? Google’s support for OSS projects is not an altruistic gesture, but rather a calculated business decision – they are supporting the processes and people that will produce the software technology they need. This is a long-term game that requires experience, skill, understanding, and patience. It is an example of humility, which is the source of all true greatness – the realization that there are some things I cannot do, even if I have huge financial resources. It is the realization that there are people out there who are much better at certain tasks than anyone in my company or anyone I can hire. It is the realization that my company organization is not the perfect environment for the development of needed software breakthroughs and highly refined building blocks, so we need to support projects that are. Because it is counterintuitive, many companies will not make this leap, especially those who have been successful in the past without it, or those building products that in the past did not require advanced software systems. Ironically, it is often the smaller companies that need OSS components the most that are resistant to adopting and contributing to OSS projects. However, the opportunity is available for anyone to participate, support, influence, and use the most advanced software innovations available today. And these innovations are largely happening in OSS projects. Your engineers can work with some of the most gifted developers in the world and learn skills that will greatly enhance their careers and benefit your organization. You will be plugged into an engine of innovation that produces value. You will have more control over the needed building blocks. You can be part of the process that produces the valuable software you need, rather than just a consumer.&lt;&#x2F;p&gt;
&lt;p&gt;Open-source projects are far from perfect. They are messy at times, as human efforts tend to be. Their future is not guaranteed, but nothing in this world is guaranteed. The lack of formal business contracts&#x2F;methods is perplexing to most business people. However, open source appears to be the best model we’ve discovered thus far for software innovation, and the results are amazing. Open source is the only supply chain that can deliver the needed &lt;strong&gt;value&lt;&#x2F;strong&gt;, innovate and &lt;strong&gt;change&lt;&#x2F;strong&gt;, manage the increasing &lt;strong&gt;complexity&lt;&#x2F;strong&gt;, give you some amount of &lt;strong&gt;control&lt;&#x2F;strong&gt;, and provide the &lt;strong&gt;culture&lt;&#x2F;strong&gt; necessary for innovation. Will you be a part of it?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Think Horses, not Zebras</title>
        <published>2023-09-22T00:00:00+00:00</published>
        <updated>2023-09-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2138/think-horses-not-zebras/"/>
        <id>https://bec-systems.com/2138/think-horses-not-zebras/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2138/think-horses-not-zebras/">&lt;p&gt;There is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&quot;&gt;popular quote&lt;&#x2F;a&gt; in medical circles:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you hear hoofbeats, think of horses, not zebras. – Dr. Theodore Woodward&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;“Zebra” is the American medical slang for arriving at a surprising, often exotic, medical diagnosis when a more commonplace explanation is more likely.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; What does this have to do with product development? Like the medical profession, we often diagnose problems – we call it &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Debugging&quot;&gt;debugging&lt;&#x2F;a&gt;. Below are three recent cases where I would have been helped by applying this approach a little more rigorously.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simple-iot-startup&quot;&gt;Simple IoT Startup&lt;&#x2F;h2&gt;
&lt;p&gt;I recently &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;issues&#x2F;598&quot;&gt;encountered a bug&lt;&#x2F;a&gt; where the compiled version of Simple IoT would not work on one of my computers. Interestingly, &lt;code&gt;go run&lt;&#x2F;code&gt; worked fine. What was the difference?&lt;&#x2F;p&gt;
&lt;p&gt;At first, it seemed that a race condition was at play – the compiled version was faster, did not have the race detector enabled, and would likely have different characteristics. SIOT is a highly concurrent application with many clients running in parallel. However, after spending some time debugging, I could not find any issues with startup, rather the NATS client in SIOT could not get data from the embedded NATS server. Again, race conditions were assumed, so I tried an external vs. embedded NATS server – no difference.&lt;&#x2F;p&gt;
&lt;p&gt;I finally observed the network traffic with Wireshark and could not observe any NATS traffic in the failing version. The NATS client was not even sending any requests. I then looked at &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; and there was no localhost entry. After adding this, everything worked properly. See &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;dont-use-localhost&#x2F;1137&quot;&gt;this discussion&lt;&#x2F;a&gt; for more analysis of this issue.&lt;&#x2F;p&gt;
&lt;p&gt;In this case, a race condition was the zebra and the missing entry in &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; was the horse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-mx8-stability&quot;&gt;i.MX8 Stability&lt;&#x2F;h2&gt;
&lt;p&gt;We recently ran into a problem with a new product that uses a Variscite &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.variscite.com&#x2F;product&#x2F;system-on-module-som&#x2F;cortex-a72&#x2F;var-som-mx8-nxp-freescale-i-mx8&#x2F;&quot;&gt;VAR-SOM-MX8&lt;&#x2F;a&gt; in a custom baseboard. The software was stable on the Variscite development baseboard, but the same SOM (System on Module) would crash in the custom hardware. The system would never crash until after the Yoe updater initramfs ran and the main rootfs was loaded. Hardware was the immediate suspect – the power supply is probably not able to handle the dynamic load when multiple cores spin up, etc. However, the power looked stable and we could not find any hardware issues. In the end, we found a missing device tree line &lt;code&gt;(&quot;fsl,imx8qm&quot;)&lt;&#x2F;code&gt; in the Linux kernel DTS file for the new design. This missing construct caused some critical kernel initialization code not to run.&lt;&#x2F;p&gt;
&lt;p&gt;In this instance, a subtle power problem was the zebra and a missing line in the DTS file was the horse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stm32h7-usb-instability&quot;&gt;STM32H7 USB Instability&lt;&#x2F;h2&gt;
&lt;p&gt;In a recent STM32H7 design, we wanted to use a High-speed USB Phy with the STM32H7 and Zephyr. This is not supported by Zephyr yet, but with a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zephyrproject-rtos&#x2F;zephyr&#x2F;issues&#x2F;57499&quot;&gt;few hacks&lt;&#x2F;a&gt;, we got it working. We are trying to push a fair amount of data over this link (10’s Mb&#x2F;sec) so some optimization and performance work was required on both the sending and receiving end. In the mix of all this, we got a new revision of the target hardware, and at some point started seeing an increase in error rates and the target not enumerating and connecting properly to the host. With a lot of moving parts and a lot of data flowing through the system, it is sometimes hard to pinpoint the problem. In this situation, we tried to narrow the scope by testing older&#x2F;newer versions of Zephyr and comparing STM32H7 reference designs to the customer hardware. We found the reference designs performed much better. We also learned that a previous version of the custom hardware also performed like the reference designs, so it appeared there was a hardware problem with the latest custom hardware.&lt;&#x2F;p&gt;
&lt;p&gt;When something worked before, and now is experiencing high levels of communication errors, the first thought was signal integrity. On the PCB design, there is a fairly long trace from the USB Phy to the connector, so this was an obvious suspect. Although we were careful to design the PCB such that the impedance of these traces was controlled, there is always the possibility that the PCB vendor did not implement the board stack-up correctly or some other strange issue. One of the engineers analyzed the trace impedance on the old and new boards with a network analyzer. This is a fairly involved test procedure that requires cutting traces, soldering coax cable to the PCB, and a fair amount of expertise. The USB traces between the two revisions looked equivalent and the impedance measured was correct. The next suspect was the high-speed signals between the MCU and Phy – we had changed some of the length matching between the two versions, so perhaps we messed something up. In the process of looking at these signals, the following was observed when scoping the data line:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2023&#x2F;09&#x2F;image.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The data line was running at two different voltage levels. The problem ended up being the power to the VDDIO pin on the phy was floating, so the signals from the phy to the MCU were not being driven at the right voltage levels. Simply scoping all the power pins on the Phy would have found this problem in a few minutes.&lt;&#x2F;p&gt;
&lt;p&gt;In this instance, signal integrity was the zebra, and a floating power pin was the horse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-can-we-learn&quot;&gt;What can we learn?&lt;&#x2F;h2&gt;
&lt;p&gt;In all of the above cases, the initial assumptions about the cause of the problem were considerably more complex than the actual problem turned out to be.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Problem&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Zebra (complex)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Horse (simple)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;SIOT Startup&lt;&#x2F;td&gt;&lt;td&gt;Race conditions&lt;&#x2F;td&gt;&lt;td&gt;Host networking config&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;i.MX8 Stability&lt;&#x2F;td&gt;&lt;td&gt;Dynamic power supply problem&lt;&#x2F;td&gt;&lt;td&gt;Missing line in device tree file&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;SMT32H7 USB errors&lt;&#x2F;td&gt;&lt;td&gt;Signal integrity&lt;&#x2F;td&gt;&lt;td&gt;Floating Phy IO power&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Hindsight is always 20&#x2F;20, so it’s easy to say we should have solved all these problems more quickly than we did. But there is always something to be learned, and I think as humans, our minds generally go to the more exotic scenario. Part of this may be overconfidence in our ability to get the simple things right, like copying a DTS file from a reference design, or supplying power to a chip. How can we possibly mess up something so simple? So we tend to overlook the simple and obvious and jump to the obscure and exotic, which exercises our most advanced abilities and knowledge. The more experienced we are, the more likely we may be to think this way. To overcome these human tendencies, it is helpful to acknowledge first that they exist (humility), and then put in place a process for future endeavors to help guide us in our debugging efforts. Consider the following maxim:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;When debugging a problem, always verify and eliminate the simple&#x2F;obvious possibilities first. Work from simple to complex.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a pragmatic approach because verifying the simple possibilities usually does not take much time, so little is lost in starting there. It may be boring or tedious, which is why we subconsciously tend to avoid these, but we can save a lot of time if we just follow this simple rule. A general process might be:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;isolate the problem as much as possible (remove unused functionality, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;write down everything you know, possibilities (all of them), and ideas of what you might try.&lt;&#x2F;li&gt;
&lt;li&gt;sort your ideas from simple to complex and work on the simple ones first.&lt;&#x2F;li&gt;
&lt;li&gt;document all tests and results.&lt;&#x2F;li&gt;
&lt;li&gt;meet as a team regularly to discuss results and brainstorm the next steps.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Some specific ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;verify basic network connectivity any time a network is involved, even if on the same machine.&lt;&#x2F;li&gt;
&lt;li&gt;don’t ignore any problem in the system. Often problems are related, and solving one problem sometimes solves another.&lt;&#x2F;li&gt;
&lt;li&gt;check that all components involved have good power.&lt;&#x2F;li&gt;
&lt;li&gt;compare to a known working reference design (both operation and design).&lt;&#x2F;li&gt;
&lt;li&gt;ask for help in relevant communities.&lt;&#x2F;li&gt;
&lt;li&gt;review and verify component pin-outs.&lt;&#x2F;li&gt;
&lt;li&gt;read the datasheets of the components involved.&lt;&#x2F;li&gt;
&lt;li&gt;read the errata for components.&lt;&#x2F;li&gt;
&lt;li&gt;work backward from a known working setup.&lt;&#x2F;li&gt;
&lt;li&gt;with web apps, open the console, and look for errors.&lt;&#x2F;li&gt;
&lt;li&gt;carefully review boot and build logs and diff with logs from working systems.&lt;&#x2F;li&gt;
&lt;li&gt;narrow the scope of the problem wherever possible.&lt;&#x2F;li&gt;
&lt;li&gt;try multiple systems.&lt;&#x2F;li&gt;
&lt;li&gt;carefully review any changes between working and non-working versions. Verify the operation of any new circuits or code.&lt;&#x2F;li&gt;
&lt;li&gt;don’t keep doing the same thing and expect different results.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Debugging is an art and a part of the development of any complex system. We must realize that our intuition often fails us in these situations and, with any human weakness, we must have a process to compensate. This debugging process can turn what is often a frustrating and scattered experience into something much more enjoyable and productive. Think horses first, and then zebras!&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Technology Trajectory</title>
        <published>2023-01-03T00:00:00+00:00</published>
        <updated>2023-01-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2084/the-technology-trajectory/"/>
        <id>https://bec-systems.com/2084/the-technology-trajectory/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2084/the-technology-trajectory/">&lt;p&gt;&lt;em&gt;See also a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;017&#x2F;&quot;&gt;podcast episode&lt;&#x2F;a&gt; where we discuss this topic.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Modern systems require the integration of technology, often from many sources. This can come in the form of processors, integrated circuits, operating systems, open-source software components, databases, messaging systems, cloud infrastructure, programming languages, build systems, frameworks, etc. All technology follows a trajectory – an example is shown below. The timeline may be short or long. Your usability threshold may be low or high, sloped right or left, etc. But the fact remains that most technology will eventually be replaced by something newer. We can debate whether or not newer is better, but the fact remains that time marches on.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;12&#x2F;image-1-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Why can’t we use a particular technology forever? With hardware, components may not be available. With software, we potentially have a little more control, but if we want to use a software component beyond the above cycle, then we have to commit to taking over maintenance. This means:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if there are bugs, we will fix them&lt;&#x2F;li&gt;
&lt;li&gt;if there are security problems, we will fix them&lt;&#x2F;li&gt;
&lt;li&gt;if there are build problems with new versions of compilers and other libs, we will fix them&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For complex, networked projects, this can be a significant undertaking.&lt;&#x2F;p&gt;
&lt;p&gt;But a far bigger issue is that of value. Open source software and corresponding ecosystems are continually improved over their life and value is added. If you use projects in your development that are being improved, then value is being added to your product. The rate at which value is being added correlates to the slope of the curve above.&lt;&#x2F;p&gt;
&lt;p&gt;To extract the most value from technology, it is generally best to adopt technology when the trajectory is rising and there is project momentum, not when everyone else has moved on. There are several reasons for this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the rate at which value is being added is greatest during this period. This makes what we are building better.&lt;&#x2F;li&gt;
&lt;li&gt;you have an opportunity to participate in and influence the development&lt;&#x2F;li&gt;
&lt;li&gt;you have more time to benefit from the technology&lt;&#x2F;li&gt;
&lt;li&gt;more support is available as there are more people participating in the project&lt;&#x2F;li&gt;
&lt;li&gt;in programming languages, there are more maintained 3rd party packages available&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We also need to select technologies that have a reasonably long life cycle as switching out a complex component can be a lot of work.&lt;&#x2F;p&gt;
&lt;p&gt;There are many other perspectives by which to evaluate technology – this is just one of them. Technology follows a trajectory from inception, growth, maturity, decline, and finally obsolescence. How do you know where a particular technology is on the curve? It is probably partly gut feeling, part experience, part asking others, and perhaps there are analytical ways to approach this as well (search engine ranking, etc). But the most important thing is to use this concept as a framework for objective thinking and evaluation. Effective technology selection is a long-term effort. We need to have a process. We may have to watch a project for a year or more to get a good feel for it. Most of us can’t significantly change the trajectory of most technologies, but we can choose where on the curve we will participate. Inefficiencies occur early and late on the curve. If we are always too early, we likely won’t get much done. If we are always too late, then our products will be a few steps behind everyone else’s.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go for IIoT Systems</title>
        <published>2022-12-09T00:00:00+00:00</published>
        <updated>2022-12-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2048/go-for-iiot-systems/"/>
        <id>https://bec-systems.com/2048/go-for-iiot-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2048/go-for-iiot-systems/">&lt;p&gt;As developers, we have many options for programming languages. On one hand, it is great to have choices. On the other hand, it can be a little overwhelming. Many times in life, we need to make decisions before we have the experience to know the best answer. There are many opinions as to what is best, and this article is just another one. There is no one-size-fits-all – a lot depends on your team and the task. In this article, we will examine the challenges we face in developing industrial IoT (IIoT) systems, review desirable attributes in a programming language, and discuss how Go meets these needs.&lt;&#x2F;p&gt;
&lt;p&gt;Peter Bourgon defines the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;peter.bourgon.org&#x2F;go-for-industrial-programming&#x2F;&quot;&gt;industrial programming context&lt;&#x2F;a&gt; as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;in a startup or corporate environment;&lt;&#x2F;li&gt;
&lt;li&gt;within a team where engineers come and go;&lt;&#x2F;li&gt;
&lt;li&gt;on code that outlives any single engineer; and&lt;&#x2F;li&gt;
&lt;li&gt;serving highly mutable business requirements.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, an industrial IoT system can be thought of as a system that gives users access and control of remote systems. There are many variations of this, but let’s focus on a simple case that is typically composed of the following pieces: Edge device (remote equipment, sensors, etc), Cloud, and Browser.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-1-1.png&quot; alt=&quot;&quot; style=&quot;width:412px;height:238px&quot;&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;IoT Components&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;All of these pieces must be dealt with at some level and will require some programming. The fundamental requirement of this system is networking – data must be moved between the above three instances. IIoT systems are inherently distributed systems. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fallacies_of_distributed_computing&quot;&gt;Distributed systems are hard&lt;&#x2F;a&gt;, thus the distributed problem needs to be solved well if you want to have a scalable, reliable IIoT system. It is natural to focus on the end application at the edge and add IIoT as an afterthought. However, this rarely works very well.&lt;&#x2F;p&gt;
&lt;p&gt;The context of this article is that of an average programmer working in small teams where engineers do a lot of different things. Many of us are not full-time programmers doing deep theoretical work, but find ourselves building these complex systems. Some of the challenges&#x2F;requirements we face include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;resources are constrained at the edge (CPU, Disk space, etc)&lt;&#x2F;li&gt;
&lt;li&gt;networks can be unreliable&lt;&#x2F;li&gt;
&lt;li&gt;config&#x2F;state needs to exist in multiple places (edge &amp;amp; cloud)&lt;&#x2F;li&gt;
&lt;li&gt;software updates need to be deployed to remote places (edge &amp;amp; cloud)&lt;&#x2F;li&gt;
&lt;li&gt;end-to-end (edge &amp;lt;-&amp;gt; browser) real-time response is often desired&lt;&#x2F;li&gt;
&lt;li&gt;many parallel operations are happening (collecting data, running rules, managing the system, etc)&lt;&#x2F;li&gt;
&lt;li&gt;physical access to edge systems so debugging problems can be difficult&lt;&#x2F;li&gt;
&lt;li&gt;edge systems typically use Embedded Linux, which can be a challenge to develop and maintain&lt;&#x2F;li&gt;
&lt;li&gt;IoT systems are inherently concurrent and distributed&lt;&#x2F;li&gt;
&lt;li&gt;many of us are doing this part-time, are not computer science gurus, and need pragmatic solutions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;attributes-of-go&quot;&gt;Attributes of Go&lt;&#x2F;h2&gt;
&lt;p&gt;Go has several attributes that make it a good fit for this problem:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;excellent reliability. I’ve &lt;a href=&quot;&#x2F;1625&#x2F;why-are-go-applications-so-reliable&#x2F;&quot;&gt;written about this before&lt;&#x2F;a&gt;. &lt;em&gt;(our systems are not crashing in the field)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;it is a compiled language &lt;em&gt;(reasonably fast and small)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;runtime is small, embedded, and efficient &lt;em&gt;(this means there is very little overhead to distributing the entire runtime with each binary. This makes deployment easy.)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;statically linked &lt;em&gt;(this makes it much easier to deploy updates as everything you need is embedded in one binary file)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;easy to embed assets &lt;em&gt;(again, this makes it easy to deploy in one file without containers)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;is garbage collected, so we don’t have to worry about managing memory &lt;em&gt;(we don’t have memory leaks, invalid pointers, and other problems that can cause field failures)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;typed language &lt;em&gt;(compiler catches more problems early instead of having crashes in the field)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;popular and well-supported &lt;em&gt;(will continue to improve and be around for a long time)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;excellent concurrency support &lt;em&gt;(a lot is going on in these systems, so this helps)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;popular in cloud and distributed systems &lt;em&gt;(there are plenty of stdlib features and 3rd party packages – metrics, monitoring, logging, communication, etc to help us build an IoT system)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;language is simple &lt;em&gt;(easy to learn, read, and maintain)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;tooling is excellent, compile is blazing fast, no Makefiles, etc, built-in support for profiling, and easy to cross-compile for other systems &lt;em&gt;(we spend less time messing around and more time deploying value to our customers)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Go is not the best solution in every case, but if your situation matches what is described above, it might be a good fit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-removes-a-lot-of-complexity&quot;&gt;Go removes a lot of complexity&lt;&#x2F;h2&gt;
&lt;p&gt;Cloud and edge systems typically run Linux. You may outsource parts of the cloud portion and perhaps even parts of the edge device, but you are generally responsible for the edge device. It must run 24&#x2F;7. You likely need to deploy updates, maintain security, and add functionality over the product lifecycle to meet customer needs. You will run into issues and need to be able to debug them. You can’t walk over to an edge or cloud system and press the reset button or hook up your JTAG debugger. Most embedded software in the past has been developed for MCUs (microcontrollers) and written in C&#x2F;C++. This is a fine solution for disconnected control-focused products, but a Linux MPU (microprocessor) solution provides you with more flexibility and functionality for data-focused connected devices that process&#x2F;store a lot of data and have complex user interfaces. Linux provides unparalleled support for a large number of devices, USB and networking functionality is reliable and mature, and it scales to processing and storing large amounts of data. In an MCU platform, you may write most of the software in the system. In some cases, you may use an RTOS (Real-time operating system), but even these are relatively small as resources are limited. In a Linux system, you are running millions of lines of code you did not write. We can use the iceberg analogy – the part underwater includes Linux and system libraries which you don’t see most of the time. The part you see above water is your application, which is a tiny portion of the total software in the system.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-3-1.png&quot; alt=&quot;&quot; style=&quot;width:387px;height:377px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Part of the value of modern systems is the huge number of software components you can reuse in your system as there are software libraries&#x2F;packages for many tasks. Building modern systems is partly the creative combination of existing&#x2F;reusable technology and the creation of new technology (the code you write).&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-7-1.png&quot; alt=&quot;&quot; style=&quot;width:400px;height:362px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;So the question arises: &lt;strong&gt;How am I going to get up to speed on all this?&lt;&#x2F;strong&gt; One solution is to minimize the amount you need to interact with the stuff underwater. If you build applications with C++, the compiler does not give you a lot of help in linking to libraries and cross-compiling to edge system architectures. (Cross compiling is compiling native code on one architecture for another – typically developing on an x86 workstation and then running on an ARM Linux target system). Thus, you need to rely on complex build systems (CMake, Yocto, Buildroot, etc). Every time you add&#x2F;update a library&#x2F;package, you are faced with the following questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;How do I integrate this library into my app build?&lt;&#x2F;li&gt;
&lt;li&gt;How do I cross-compile to my edge system?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It’s not easy, thus projects such as Yocto and Buildroot exist. All developers need to have a cross tool-chain (compiler and libraries) installed on their development computer that matches the libraries in the edge system. Deploying an application update often means deploying additional libraries, or library updates. So we add container technology to try to manage all this, which is another layer of complexity.&lt;&#x2F;p&gt;
&lt;p&gt;Some solutions (like Raspbian for the Raspberry PI) advocate developing directly on the target device to avoid the complexity of cross-compiling. This works fine for small one-off maker projects, but for the development of large industrial programs, it is a poor solution as it is like developing on a PC from the 90s. Sure, cross-compiling is easier, but everything else is much harder.&lt;&#x2F;p&gt;
&lt;p&gt;Python or Node.js may look attractive in that they are easier to program than C++ and the program is interpreted on the target device, but many of the underlying packages for these languages depend on C++ code, as interpreted languages are slow, as a result the build problem is worse because it is even more difficult to cross-compile this code in the Python and Node.js build systems. Additionally, a separate run-time is required on the edge system which is relatively large and must be kept in sync with the application.&lt;&#x2F;p&gt;
&lt;p&gt;Go sidesteps most of this because it is a mostly pure ecosystem. There are no host library dependencies in a pure Go application – everything it needs is embedded in a single binary file (typically 2-10MB compressed). The Go standard library is rich and has many needed functions. Additionally, there is a rich selection of pure Go &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;&quot;&gt;3rd party packages&lt;&#x2F;a&gt; that cover most other needs. Adding packages to a Go application is as simple as &lt;code&gt;go get some&#x2F;package&#x2F;name&lt;&#x2F;code&gt;. There are no development tool requirements other than a standard Go installation and an editor. No complex build tools are required to add 3rd party packages or to cross-compile to different target systems (macOS, Windows, Linux). It has built-in support for profiling. If it crashes, you always get a stack trace. It’s so easy, and the learning curve is small.&lt;&#x2F;p&gt;
&lt;p&gt;Many software tools today add layer upon layer to solve the problems with the underlying technology. While this helps in some cases, it often adds additional complexity. You can’t gloss over complexity – when things go wrong, you still need to understand the entire stack anyway. Abstraction has its place but can only take you so far. If there are problems in one technology layer, adding additional layers sometimes just makes it worse. Go &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;npf.io&#x2F;2014&#x2F;10&#x2F;why-everyone-hates-go&#x2F;&quot;&gt;threw everything out and started over&lt;&#x2F;a&gt;. Simplicity is the only sustainable approach to technology.&lt;&#x2F;p&gt;
&lt;p&gt;Go is a relatively new language (released in 2009), so many people have not heard of it. Learning a new language does take some time*.* Go has a small learning curve, but that is nothing compared to the learning curve of building, deploying, and maintaining C++ code in edge systems. Go allows you to quickly become productive and spend very little time fighting tools over the product lifecycle. Moving your Go application forward over time often does not require any changes to the base Linux system because they are decoupled.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-is-familiar-and-simple&quot;&gt;Go is familiar and simple&lt;&#x2F;h2&gt;
&lt;p&gt;Google &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;commandcenter.blogspot.com&#x2F;2012&#x2F;06&#x2F;less-is-exponentially-more.html&quot;&gt;originally developed Go&lt;&#x2F;a&gt; as a solution to the pain they were experiencing with C++, and they are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;go.dev&#x2F;blog&#x2F;13years&quot;&gt;still investing in it&lt;&#x2F;a&gt;. Go syntax is similar to C and was developed by some of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Go_(programming_language)&quot;&gt;same people&lt;&#x2F;a&gt; who were involved in the development of the C language and Unix back in the 1970s. Thus, it feels very familiar to those of us who have spent time developing in C, Java, C#, etc. Go eschews the complexity that has overtaken C++. Language features are added slowly and carefully. Compile errors are generally easy to understand and debug. Backward compatibility has been excellent. Since 2014, I’ve implemented several systems in Go and have not had any significant issues after updating the Go or 3rd party package versions. Go developers take API compatibility seriously, so this helps.&lt;&#x2F;p&gt;
&lt;p&gt;Go is a simple language but does not force you to do things correctly (as a language like Rust does). You can still make a concurrency mess with channels. Go has &lt;code&gt;nil&lt;&#x2F;code&gt; values, so you can still crash your program if you try to reference a &lt;code&gt;nil&lt;&#x2F;code&gt;. If you don’t check returned error values, you’ll probably run into problems. But, if you follow a few simple best practices and idioms, it works well and is a nice experience. Simple programming languages are much easier to read and maintain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-concurrency-support&quot;&gt;Go Concurrency Support&lt;&#x2F;h2&gt;
&lt;p&gt;IIoT systems have a lot going on, so you need good support for concurrency. Interpreted languages like Python and Node.js are weak in these areas. Go has excellent support for concurrency by providing channels and the &lt;code&gt;go&lt;&#x2F;code&gt; keyword as language features. This allows for running concurrent tasks and communication between them with very little overhead. Go channels are easy to misuse, so it requires a little effort and practice to learn how to use them correctly, but once understood, it is a very simple and reliable way to manage concurrency in a system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-is-an-internet-language&quot;&gt;Go is an Internet language&lt;&#x2F;h2&gt;
&lt;p&gt;While older languages like C&#x2F;C++ and Python have been excellent tools for solving programming problems in the past (and are still the best in some domains like MCU development, machine learning, etc), the problems we are solving in IIoT systems are different today in several ways:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;we are dependent on large ecosystems of 3rd party packages to implement all the functionality we need&lt;&#x2F;li&gt;
&lt;li&gt;we need better tools for concurrency and distributed systems&lt;&#x2F;li&gt;
&lt;li&gt;we need simpler models for network programming&lt;&#x2F;li&gt;
&lt;li&gt;we need software that is easier to build and deploy&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Communication between systems is the fundamental problem IoT systems solve and Go is good at this. Go is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;drewdevault.com&#x2F;2021&#x2F;04&#x2F;02&#x2F;Go-is-a-great-language.html&quot;&gt;best-in-class for a new breed of software: an Internet programming language&lt;&#x2F;a&gt;. As evidence of this, most cloud and distributed software infrastructure is written in Go these days (Kubernetes, Docker, NATS, etc). Cloud companies that scale to thousands of systems are very sensitive to cost, thus they need efficient platforms. This efficiency in Go also benefits us at the edge where resources are constrained. An added benefit is that you can write your edge and cloud applications in the same programming language.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-go-has-no-gui-support&quot;&gt;But Go has no GUI support …&lt;&#x2F;h2&gt;
&lt;p&gt;Although there have been many excellent efforts to develop a native GUI library for Go, none of them have emerged as the standard. There is a good reason for this … &lt;strong&gt;the browser is the standard UI platform these days&lt;&#x2F;strong&gt;. Nothing else can come close to touching its capabilities. It is cross-platform, reasonably performant, and very well-supported. The browser has so many options for programming, packages, etc. The browser has built-in support for video and other forms of media and is highly optimized. Developing applications in the browser is more difficult to get started than in a C++ GUI toolkit. But there is a much richer ecosystem of packages and functionality available in the browser platform. The browser platform is stable and you are ensured of backward compatibility – it will be around and well-supported for a long time. The web platform is built on solid engineering principles that have proven to scale. Many UI technologies designed to replace the browser programming model have come and gone: Java, Macromedia Flash, and Microsoft .net – yet the standard browser programming model of HTML5 + Javascript has displaced all of these and is growing at an astounding rate. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;flutter.dev&#x2F;&quot;&gt;Google Flutter&lt;&#x2F;a&gt; is the latest attempt to displace the web platform, but it remains to be seen yet if it will be successful. Most C++ GUI toolkits are highly dependent on a single company that may be here today and gone tomorrow (look at the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Qt_(software)&quot;&gt;history of Qt&lt;&#x2F;a&gt; for an example), or licensing requirements &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=25344826&quot;&gt;may change&lt;&#x2F;a&gt; at any time – there are a lot of unknowns. Plus, with the web platform, you can view the UI remotely just as well as locally. You can also use the same UI building blocks in the cloud as in the edge device. If designed correctly, web applications also function very well on mobile devices, eliminating the need to develop separate mobile apps. With the web platform you can address all of the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;on-device LCD UI (runs a browser full screen)&lt;&#x2F;li&gt;
&lt;li&gt;remote access to the device using a browser&lt;&#x2F;li&gt;
&lt;li&gt;cloud application UI&lt;&#x2F;li&gt;
&lt;li&gt;mobile device access (browser, PWA, Cordova, etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The experience of a native phone app might be slightly better than a web application on mobile devices, but how many of us can afford to develop 4 different UI applications for a product (native, web, Android, iOS) when one will do in most cases? The question is not what is possible or technically best, but what is practical with the limited resources we have.&lt;&#x2F;p&gt;
&lt;p&gt;Languages like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elm-lang.org&#x2F;&quot;&gt;Elm&lt;&#x2F;a&gt; simplify front-end (web) development in many of the same ways that Go has simplified back-end development.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-go-is-not-the-best-at&quot;&gt;But Go is not the best at …&lt;&#x2F;h2&gt;
&lt;p&gt;Very true – Go is not as easy as Python, as widespread as C++, as popular as Javascript, as safe as Rust, or as good at concurrency as Elixir. But, Go is almost as good as the best at everything and its tooling is much better than any other language ecosystem – especially for distributed applications that need to be deployed to remote and different architectures. It does not have any of the significant drawbacks other languages have. And especially for networked IoT systems, it is an excellent choice. The below decision matrix likely reflects my biases, but illustrates this point (green is best, red is worst):&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-4-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;but-what-if-i-need-to-use-c&quot;&gt;But what if I need to use C++ …&lt;&#x2F;h2&gt;
&lt;p&gt;There are certainly cases where you may need to use C++ or some other language. You may choose to implement a native UI using Qt or LVGL. Machine learning code is often written in C++. There is no reason your system needs to be written in one language – Go can be used in combination with other languages. There are several ways this can be implemented:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;call the C++ code directly from Go (CGO)&lt;&#x2F;li&gt;
&lt;li&gt;run the C++ and Go code as separate applications and communicate between them using a message bus&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Method #2 is preferred in many cases as it keeps your Go code clean, and the C++ code can be built using standard C++ build systems instead of trying to force the Go build system to build C++. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;&quot;&gt;Simple IoT&lt;&#x2F;a&gt; is one framework that is designed for exactly this scenario:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-5-1.png&quot; alt=&quot;&quot; style=&quot;width:588px;height:329px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;This architecture keeps your Go code easy to build&#x2F;develop&#x2F;deploy. Your core logic, which manages config&#x2F;state and communicates with other systems, can be written in Go. This core logic must be reliable and easy to maintain. Specialty code like machine learning models can be dedicated C++ applications. NATS is a modern message bus written in Go that is easy to embed in any Go program and is a great way to connect different applications.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-6-1.png&quot; alt=&quot;&quot; style=&quot;width:495px;height:297px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;optimize-for-where-you-will-spend-most-of-your-time&quot;&gt;Optimize for where you will spend most of your time&lt;&#x2F;h2&gt;
&lt;p&gt;Linux-based IoT edge systems have plenty of memory, storage, and processing power. Thus, features are continually added over the product lifecycle, which can be 5-10 years in an industrial system. The time spent maintaining and improving a product often swamps the initial development. Therefore, it makes sense to optimize for the long term – adding features and deploying updates over the next ten years. Go makes it easy to build and deploy updates with the latest Go and package versions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;friction&quot;&gt;Friction&lt;&#x2F;h2&gt;
&lt;p&gt;Developer productivity is difficult to fully understand. We often think of the features we need in our languages&#x2F;tools. Commercial software vendors focus on features. Development methodologies are designed to increase productivity by better organizing what needs to be done. But another aspect that is easy to overlook is the amount of time we spend messing around working on stuff that does not directly add value to our product. I call this “friction.” This friction can manifest itself in unforeseen problems that are more common in complex systems: learning curves, build issues, issues with libraries&#x2F;packages, lack of flexibility, security problems, deployment problems, bugs, race conditions, stability problems, technical debt, lack of control over parts of the system, etc. Go does an excellent job of reducing friction in the development process. You focus on what needs to be done, and the rest is mostly invisible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;In this article, we explored many of the attributes of Go that make it ideal for implementing IoT systems. Go provides a modern programming ecosystem where the build tools are first class, the language is simple, and there is little friction to get things done. Go also provides features such as garbage collection and concurrency support in the language which are very helpful in IoT systems where data is distributed and a lot is going on. Go is an Internet language that is increasingly used to develop distributed systems, which includes IoT systems. It is a stable (almost boring in many respects) technology and is a great option for developers who are familiar with C&#x2F;C++ and want to expand into Embedded Linux&#x2F;IoT – the skills you have are very applicable in Go.&lt;&#x2F;p&gt;
&lt;p&gt;What is the main constraint in your projects?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Application performance?&lt;&#x2F;li&gt;
&lt;li&gt;Getting things done and shipped?&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If #1, then perhaps C++ or Rust is a good choice. If #2, then take a look at Go.&lt;&#x2F;p&gt;
&lt;p&gt;Go is not the best solution for every team&#x2F;project, but for the scenario described in this article, it has worked incredibly well. With Go, we can develop and deploy remote systems with confidence.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Layered, Event, and Data-Centric Architectures in Distributed IoT Systems</title>
        <published>2022-06-14T00:00:00+00:00</published>
        <updated>2022-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1884/layered-event-and-data-centric-architectures-in-distributed-iot-systems/"/>
        <id>https://bec-systems.com/1884/layered-event-and-data-centric-architectures-in-distributed-iot-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1884/layered-event-and-data-centric-architectures-in-distributed-iot-systems/">&lt;p&gt;With the advent of the browser, cloud, embedded Linux systems, and networked microcontrollers, distributed systems are everywhere. There are many models for communication in distributed systems – we will look at the tradeoffs between three of them. There are many perspectives to consider – initial implementation, client libraries, maintenance, adding features now and in the future, client compute and storage requirements, network bandwidth,  data structure, etc. This article will discuss a number of these concerns and present several options.&lt;&#x2F;p&gt;
&lt;p&gt;The motivation for this discussion is synchronizing data in IoT systems where we have the following requirements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Data (state or configuration) can be changed anywhere, at edge devices or in the cloud, and this data needs to be synchronized seamlessly between instances. Sensors, users, rules, etc. can all change data. Some edge systems have a local display where users can modify the configuration locally as well as in the cloud. Rules can also run in the cloud or on edge devices and modify state.&lt;&#x2F;li&gt;
&lt;li&gt;Data bandwidth and allowance is limited in some IoT systems (example Cat-M modems (&amp;lt; 100kb&#x2F;s) and cellular IoT plans (&amp;lt; 50MB&#x2F;month)). Additionally, connectivity is not always reliable, and systems need to continue operating if not connected.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first is the &lt;em&gt;&lt;strong&gt;Layered&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; model. In this model, various instances talk directly to other instances. If any information needs to be shared, it is sent directly through an API (application programming interface) call using REST, CoAP, and other protocols – sometimes traveling through multiple layers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The layered, or API model’s advantage is simplicity – almost anything can connect to a REST endpoint. Most networked devices have built-in support for HTTP. Many companies provide services through REST APIs. Polling is typically used in the layered model to determine when things change, which limits the response time to the polling frequency. There are mechanisms that can be used in a layered architecture to obtain real-time response such as HTTP long polling, WebSockets, Server SIde Events (SSE), callbacks&#x2F;webhooks, CoAP subscribe&#x2F;notify, etc. However, an event bus is generally a much cleaner implementation if real-time response is needed. Firewall and security concerns can also make callbacks impractical on edge devices. If a device at the end of a layered architecture needs new information, often multiple layers need to be modified to handle this new information, which can make changes expensive.&lt;&#x2F;p&gt;
&lt;p&gt;A second model is the &lt;strong&gt;&lt;em&gt;Event&lt;&#x2F;em&gt; or &lt;em&gt;Message Bus&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; model. Implementations include NATS, MQTT, Kafka, and many others. In this model, every instance in the system is connected to a message bus. All data communication is routed through the bus. Clients can post or subscribe to topics of interest so that updates happen in real-time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some advantages of the event bus include real-time response and streaming workflows. All communication and information is on the bus, so if an instance needs to send or receive some information, it simply subscribes or publishes it. Event buses often leverage one connection to the message server so that each message does not need to establish a new connection, which can &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hivemq.com&#x2F;blog&#x2F;mqtt-vs-http-protocols-in-iot-iiot&#x2F;&quot;&gt;bring some efficiencies and reduce needed resources&lt;&#x2F;a&gt; (such as number of TCP connections). However, the event bus protocol is considerably more complicated than REST, so a message bus library is typically required to implement the client application.&lt;&#x2F;p&gt;
&lt;p&gt;The third model is the &lt;em&gt;&lt;strong&gt;Data-Centric&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; model. In this model, each client instance contains a set of data it is interested in. In the below example, the cloud system has an aggregate of all the data in a system, and the browser and edge instances are subscribed to a subset of the data they are interested in or have access to, represented by the different colored blocks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-3.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The data models the entire system, so if an action (setting an output, sending a notification, etc) is required, a bit of data is changed, and then the system takes action based on this data. The needed data is replicated to each instance in the system and is automatically synchronized in any direction when it changes.&lt;&#x2F;p&gt;
&lt;p&gt;To all you Go programmers out there, this may immediately raise a big red flag. What? Communicate by sharing common data?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don’t communicate by sharing memory; share memory by communicating.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;R. Pike&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Pike’s comment is typically used in the context of an application where multiple threads (goroutines) share data in memory, and locks are used to keep multiple threads from writing to it at the same time. This model can be hard to reason about due to race conditions. An analogous model in distributed systems may be a common database that all instances use and all config&#x2F;state is stored in this remote database. Locks may be analogous to database transactions. A common database is a good solution for many cloud based distributed systems where everything is always connected and, and this model allows data to be modified from multiple locations. However, with IoT systems, we have the following constraints that make it impractical to use a single remote database as our primary configuration&#x2F;state data store for everything in the system:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;We often don’t have the network bandwidth or data allowance (ex: LoRaWAN or Cat-M modems and low cost cellular IoT plans)&lt;&#x2F;li&gt;
&lt;li&gt;Network connections are unreliable, and edge instances need to continue working (collect data, run rules, etc.), even if the network is down.&lt;&#x2F;li&gt;
&lt;li&gt;Network latency can be long – especially with low bandwidth connections.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This leads us to a &lt;strong&gt;“local first”&lt;&#x2F;strong&gt; data model, where all configuration and state needs to be stored local to an edge device. However, this data is often viewed or edited in the cloud, so it also needs to be present there. We could craft new data structures and messages for every new bit of data and send custom messages over a REST API or event bus every time anything on either end changes. However, a simpler approach is to design a generic data model that can hold any kind of data, and then a mechanism to synchronize this generic data model. Then, adding functionality is much simpler as we can write&#x2F;read data wherever needed, and synchronization between instances happens automatically with no extra effort. However, we have to learn to work within the constraints of the data model. A new feature might involve tweaking the UI and writing some code on the edge instance. Often, nothing in the middle needs to change:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;ref&#x2F;images&#x2F;constant-vs-varying-system-parts.png&quot; alt=&quot;Constant vs Varying parts of System&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Each instance has its own local copy of whatever data it needs. But instead of the developer needing to manually manage the synchronization of data between systems using custom messages, changes to the data are automatically synchronized in any direction.&lt;&#x2F;p&gt;
&lt;p&gt;The data-centric architecture requires more computing resources and storage to run it – typically an embedded Linux system. The below chart illustrates the trade-offs between client complexity and programming simplicity.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-4.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For less capable networked devices such as microcontrollers (ex: Arduino), you may be limited to a layered approach, as HTTP may be the only supported protocol. However, as microcontrollers advance, many of them are now supporting event buses such as MQTT. The cost of a data-centric architecture is an up-front cost when building the base system. As time goes on, the incremental costs of adding features is much lower. Since adding features is typically a continuous, long term exercise, the initial cost is paid back many times over. A data-centric architecture also introduces some discipline in how data is structured, stored, and synchronized. This helps avoid the technical debt that rapidly accrues in less structured approaches.&lt;&#x2F;p&gt;
&lt;p&gt;All architectures have their place. If the application is fixed in functionality, and you only need to send a temperature reading to the cloud once per hour and this is never going to change, then a microcontroller with a layered architecture is fine. If you need to send data in both directions and real-time response is needed, then moving up to an event bus makes sense. If you have devices that have a decent amount of configuration that can be modified at the device and in the cloud, runs rules locally, and features will continually be added to the system, then a data-centric architecture is beneficial. The data-centric architecture requires a more complex system to start with, but the incremental effort to add features down the road is drastically reduced because the developer does not need to worry about the data storage&#x2F;synchronization problem. Additionally, the data model is available at each instance, so programming is simpler.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to support multiple architectures in one system. For example, in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;ref&#x2F;architecture.html&quot;&gt;Simple IoT&lt;&#x2F;a&gt; all data modifications are sent over an event bus which is the primary &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;ref&#x2F;api.html#nats&quot;&gt;programming API&lt;&#x2F;a&gt;. A client can connect to the event bus of a local or remote Simple IoT instance. If the local and remote instances are connected using an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;user&#x2F;sync.html&quot;&gt;upstream sync connection&lt;&#x2F;a&gt;, then writes to the common data-set of either instance are automatically synchronized to the other. If a client does not want to implement a local data store, they can connect to a remote instance’s event bus. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nats.io&#x2F;nats-concepts&#x2F;jetstream&quot;&gt;NATS JetStream&lt;&#x2F;a&gt; is another example of a store built on top of an event bus. Some event bus implementations like NATS allow for easy &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nats.io&#x2F;nats-concepts&#x2F;core-nats&#x2F;reqreply&quot;&gt;request&#x2F;response transactions&lt;&#x2F;a&gt;, which is similar to a layered REST&#x2F;RPC type interface. Thus clients in a system like Simple IoT can range from simple HTTP clients, to mid-range event-bus clients, to advanced Linux based, data-centric clients with a local data store.&lt;&#x2F;p&gt;
&lt;p&gt;In computer science, focusing on data is typically the right approach.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I will, in fact, claim that the difference between a bad programmer and a good one is whether he considers his code or his data structures more important. Bad programmers worry about the code. Good programmers worry about data structures and their relationships.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Linus Torvalds&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Fred Brooks&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Distributed systems are no different – the focus needs to be on the data. Synchronizing data efficiently and reliably between distributed instances is a hard problem to solve, and the focus of much research and development effort today (example: the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;riffle.systems&#x2F;&quot;&gt;Riffle project&lt;&#x2F;a&gt;). This requires some up-front thought, planning, and constraints, but the payoff is simpler data models that result in systems that are more reliable and cost effective over the product life-cycle. Data-centric architectures free developers from the tedium of synchronizing data and allows focus on the application problem at hand. Data-centric architectures also provide discipline and structure around the data synchronization problem that helps avoid technical dept build-up which is a great impediment in the flow of value to end users.&lt;&#x2F;p&gt;
&lt;p&gt;Each distributed system architecture has its place, and with a correct implementation, we can support multiple architectures in one system. This gives us the option to support simple as well as advanced clients, depending on the need. However, as the cost of advanced MPUs systems running Linux such as the Raspberry PI continue to fall, deploying advanced IoT clients to the edge makes a lot of sense.&lt;&#x2F;p&gt;
&lt;p&gt;In future articles, we’ll examine in more depth the techniques used to store and synchronize data in data-centric architectures.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;em&gt;Khem Raj&lt;&#x2F;em&gt;&lt;&#x2F;em&gt;, &lt;em&gt;Bruce Stansell, Gina Brake, and Collin Brake for reading drafts of this.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Business Contracts</title>
        <published>2022-03-21T00:00:00+00:00</published>
        <updated>2022-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1563/business-contracts/"/>
        <id>https://bec-systems.com/1563/business-contracts/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1563/business-contracts/">&lt;p&gt;Business contracts are often executed when two companies work together. At the most basic level, a contract should describe a common understanding between the two parties. The contract should assist and aid the relationship. However, many contracts are written by lawyers with the primary goal of covering every legal loophole and taking every legal advantage possible for their clients. This often results in contracts that are very long, filled with legal jargon, benefiting only one party, and in general, a burden to process.&lt;&#x2F;p&gt;
&lt;p&gt;For a business relationship to be successful and sustainable, there has to be &lt;strong&gt;value&lt;&#x2F;strong&gt; for both parties and there has to be &lt;strong&gt;trust&lt;&#x2F;strong&gt;. If these two key ingredients are lacking, there is little motivation to continue the relationship.&lt;&#x2F;p&gt;
&lt;p&gt;We can look at business relationships as a positive-sum game, or a zero-sum game. A positive-sum game is where the relationship is structured as a win-win – both parties find good value in the relationship and are motivated to continue it. There is a belief that the “pie” of opportunity will grow through their combined efforts. The engagement is voluntary and not constrained by force or compulsion. Zero-sum thinking is where one party is always trying to gain the maximum advantage over the other party. This is the “fixed pie” mentality where we think the resources in business are fixed, and if anyone else gains something, it is my loss. This attitude is often found in purchasing departments where they are trying to obtain the lowest possible price for a good or service, net 60 payment terms, etc. I recall in one case a manager of a company exclaiming, as we went into a meeting with a vendor, “Let’s go beat ’em up!”&lt;&#x2F;p&gt;
&lt;p&gt;Business relationships are more complex than getting the lowest price or the greatest legal advantage. The people&#x2F;companies you want to do business with are likely already busy. They likely have plenty of opportunities. They will seek engagements with those who play the positive-sum game. If a company plays the zero-sum game, they will end up doing business with second rate companies who don’t have any other choice. They won’t get good service, and trust in the relationship will be lacking. They will be forced to hop from one vendor or customer to other. There will be few long term relationships. As Bob Metcalfe &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.technologyreview.com&#x2F;s&#x2F;400489&#x2F;invention-is-a-flower-innovation-is-a-weed&#x2F;&quot;&gt;once wrote&lt;&#x2F;a&gt;, &lt;em&gt;“First, don’t “hire” anyone.  B people hire C people – they collect resumes and choose the person they want to honor with a job. A people recruit A people.“&lt;&#x2F;em&gt; The same applies to business relationships.&lt;&#x2F;p&gt;
&lt;p&gt;With this background, let’s examine the topic of contracts a company may present to an independent contractor or consultant providing services to the company.&lt;&#x2F;p&gt;
&lt;p&gt;Again, the best developers (the ones you want) are successful and busy. They will not mess around in business relationships where people are playing the zero-sum game. They are successful because they are trustworthy and expect the same in return. They are generous with their time and knowledge because they understand the universal law that &lt;strong&gt;the more you give, the more comes back to you.&lt;&#x2F;strong&gt; But they also expect the same in return. They are confident in their abilities and do not take measures that lock their customers into their services, but on the contrary, make themselves “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&quot;&gt;easy to fire&lt;&#x2F;a&gt;.”&lt;&#x2F;p&gt;
&lt;p&gt;A fundamental problem with trust is that people generally don’t tell you when they don’t trust you. Actions that damage trust are likely unintentional (otherwise you would not do them), but you never get feedback on this. So, I’m giving you a hint now – an onerous contract, with one-sided indemnification clauses, damages trust. It tells the other party that “I might take advantage of you.” It implies that if bad things happen due to a product flaw, “you could be on the hook.” It sows seeds of doubt. Most often, this is likely not the thought of the company presenting the contract, and the contract language is just the result of lawyers trying to do an exceptional job of protecting their client from any possible liability. However, a contract is still a contract. If disaster strikes, the contract will be used in court by various parties trying to recoup damages. Products are often sold over a long time (5-10 years or more). Companies often change owners. Therefore, it is very important that a contract be fair and just. When a developer is presented with an onerous contract, immediately the question arises – can I trust this company? Is it worth it? Even if the project goes forward, it will be with some reserve and guard. It will not be with the wholehearted attitude that is an ingredient for success.&lt;&#x2F;p&gt;
&lt;p&gt;As we consider indemnification phrases in a contract, we need to establish who should assume liability for a product: 1) a consultant&#x2F;contractor who is billing by the hour, or 2) the company selling the product over a span of many years? Risk should be proportional to reward. A hourly contract developer has no reward for a product’s success, other than the baseline costs of doing the development. The company selling the product is the one who will potentially reap the multiplying rewards of a successful product. Therefore, they should be the ones who bear the risk as well. It is not just to expect otherwise. In the situation where a developer is providing consulting or contracting services to a larger company developing a product, it is important that the contract clearly state that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The Company assumes sole responsibility for all testing of the Work, including but not limited to software and hardware, and also assumes sole liability for any use or misuse of the Work developed by Contractor for the Company.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An argument may be made to the developer – you are not a lawsuit target because you are not a large company with deep pockets – so just sign the contract. This may be true, but what if the consultant does grow the business to the point where there are more assets? Products live a long time – a lot can change. As mentioned before, a company can change hands. If there is a lawsuit, then anything is possible.&lt;&#x2F;p&gt;
&lt;p&gt;An individual developer has limited control of the development of a complex project and the resulting product. (We are not talking about fixed-bid turnkey product design where a larger company designs the entire product, but rather hourly development services). Typically, there is extensive involvement from other developers. The contract developer does not control how the product is manufactured, marketed, sold, supported, or even how other parts of the system are developed. In complex systems there will be bugs, and often there are time to market pressures that prevent extensive testing and verification. These are all factors that are out of the developer’s control and are choices made by the product owner. Again, this further illustrates that those who are ultimately in control of a product (the owner) should be responsible for any liability the product might bring.&lt;&#x2F;p&gt;
&lt;p&gt;This brings us to a common concern of the company – they want to be sure the product is developed to professional standards.  A contract phrase might be: &lt;em&gt;“Contractor hereby warrants that its work shall be of professional quality and performed consistent with generally accepted industry standards”&lt;&#x2F;em&gt; Who defines these standards? How will they be defined in court? The reality is that few developers have the time and resources to really do the job they want to do. Schedules are always pressing, forcing compromises. Ultimately the product owner makes the decisions concerning these trade-offs – not the developer. Time to market is critical. Therefore it is difficult for a developer to warrant any work will be at any particular industry standard – as the product owner is ultimately in control. The universal laws of reality apply: “Good-Fast-Cheap” – pick two – all three do not exist. In any product development effort, there are compromises.&lt;&#x2F;p&gt;
&lt;p&gt;There is a very practical way to handle the concern that a company’s product is being developed to their standards, and that is to encourage collaboration and openness between all developers on the project. Make sure all source code and design files are shared in Git repositories that are easily accessible to all developers – both employees and contractors. Encourage all developers to work on any part of the system needed to get their job done. Google &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cacm.acm.org&#x2F;magazines&#x2F;2016&#x2F;7&#x2F;204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository&#x2F;fulltext&quot;&gt;does&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@Jakeherringbone&#x2F;you-too-can-love-the-monorepo-d95d1d6fcebe&quot;&gt;it&lt;&#x2F;a&gt; – maybe you should, too. Discourage engineering “turf” where developers feel they “own” something in the sense that no-one else should mess with it. This is essentially the process used in Open Source Software, and successful companies have adopted these practices – the results speak for themselves. If this works in a large company, is there any excuse for not doing this in a small company? Open source projects don’t have contracts that specify all contributors have to do a good job, yet open source projects contain some of the highest quality code available. Peer review and doing your work in public (even if only within a company) is a powerful motivator. Because the development is in an open environment, it is quickly evident who is going a good job and who is not. The same dynamic can happen in a company. If there is open collaboration, frequent integration, and early testing, you will soon get a good feel if developers are efficient and are generating work that is of “professional quality.” Share weekly reports with the entire team of what each developer did and how much time they spent on the project. This will produce a level of accountability among peers that will far exceed what any manager can force. If someone is spending excessive amounts of time and not getting anything done, other developers will start to question it. And you will know of problems early in the project at a time when you can do something about it, rather than after a product has been sold in quantity and some horrible defect arises that results in lawsuits. Which is the better option? To summarize:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;If a company wants to ensure quality work is being done by their developers, then they must foster a collaborative, transparent development environment where:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;All development is done in the “open” in Git repositories that the entire team has access to.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Any developer can contribute to any part of the system required to do their job.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Integration is done often.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Product testing, by the owner, is started early in the development cycle.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;No amount of contract legalese can come close to being as effective as the above.&lt;&#x2F;p&gt;
&lt;p&gt;Whether you intend it or not, your legal contracts are both a reflection and driver of your company culture, and its resulting success. They impact the people you will attract – both employees and contractors.  Do your contracts reflect a fair and generous mindset where you are willing to take responsibility for the things you should take responsibility for?  Do they turn away or create reserve in people you need the most? This is a serious issue because the best people often come through referrals. Will a developer recommend their talented and busy friends if they are required to sign uncomfortable contracts that must be negotiated to even approach an acceptable level? Any friction in this process is slowing you down. Yes, a one-sided legal contract that takes everything you can get may save you some liability in the unlikely event of a product lawsuit. But it also has the effect of introducing friction in relationships that are key to your product being completed in the first place. Which is more important? Which should have priority? In summary, a contract should:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;clearly represent the concerns of both parties&lt;&#x2F;li&gt;
&lt;li&gt;document what is expected&lt;&#x2F;li&gt;
&lt;li&gt;not be one-sided&lt;&#x2F;li&gt;
&lt;li&gt;be fair&lt;&#x2F;li&gt;
&lt;li&gt;avoid complex legal jargon as much as possible&lt;&#x2F;li&gt;
&lt;li&gt;aid, not hinder the business relationship&lt;&#x2F;li&gt;
&lt;li&gt;include provisions for how the relationship will be terminated, if needed&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’ve been working as a consultant for 20 years. My most successful and longest relationships have been with companies where I have never executed a single contract. Is this a coincidence? Is it cause or effect? I don’t claim to know, but my experiences resonate with the words of Seth Godin:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A handshake deal, on the other hand, is about the future. Either side can claim loopholes or wriggle out of a commitment, but the consequence is clear—if you disappoint us, we won’t be back for more. The participant in a handshake deal is investing in the future, doing more now in exchange for the benefits that trust and delight and consistency bring going forward.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;from: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;seths.blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past&#x2F;&quot;&gt;https:&#x2F;&#x2F;seths.blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Somehow an essay about contracts has morphed into a discourse on company culture, development practices, and ultimately success. This is the power of writing – it helps you connect concepts that you did not previously realize were connected. In the end, everything is connected. Your contracts, your company culture, the type of people you attract, etc. It all matters.&lt;&#x2F;p&gt;
&lt;p&gt;References:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.technologyreview.com&#x2F;s&#x2F;400489&#x2F;invention-is-a-flower-innovation-is-a-weed&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.technologyreview.com&#x2F;s&#x2F;400489&#x2F;invention-is-a-flower-innovation-is-a-weed&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&quot;&gt;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sethgodin.typepad.com&#x2F;seths_blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past.html&quot;&gt;http:&#x2F;&#x2F;sethgodin.typepad.com&#x2F;seths_blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;badsoftware.com&#x2F;contract1.htm&quot;&gt;http:&#x2F;&#x2F;badsoftware.com&#x2F;contract1.htm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cacm.acm.org&#x2F;magazines&#x2F;2016&#x2F;7&#x2F;204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository&#x2F;fulltext&quot;&gt;https:&#x2F;&#x2F;cacm.acm.org&#x2F;magazines&#x2F;2016&#x2F;7&#x2F;204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository&#x2F;fulltext&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@Jakeherringbone&#x2F;you-too-can-love-the-monorepo-d95d1d6fcebe&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;@Jakeherringbone&#x2F;you-too-can-love-the-monorepo-d95d1d6fcebe&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.clearviewlegal.co.uk&#x2F;ohlawdy&#x2F;contracts-are-communication&quot;&gt;https:&#x2F;&#x2F;www.clearviewlegal.co.uk&#x2F;ohlawdy&#x2F;contracts-are-communication&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Technology</title>
        <published>2020-11-27T00:00:00+00:00</published>
        <updated>2020-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1841/technology/"/>
        <id>https://bec-systems.com/1841/technology/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1841/technology/">&lt;p&gt;The fire of information technology – will you use it:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;to &lt;strong&gt;create&lt;&#x2F;strong&gt; or consume?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;comfort&lt;&#x2F;strong&gt; or torment?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;education&lt;&#x2F;strong&gt; or entertainment?&lt;&#x2F;li&gt;
&lt;li&gt;as a &lt;strong&gt;tool&lt;&#x2F;strong&gt; or weapon?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;temper&lt;&#x2F;strong&gt; or incite?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;community&lt;&#x2F;strong&gt; or faction?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;harmony&lt;&#x2F;strong&gt; or rebellion?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;encourage&lt;&#x2F;strong&gt; or discourage?&lt;&#x2F;li&gt;
&lt;li&gt;to spread &lt;strong&gt;light&lt;&#x2F;strong&gt; or darkness?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;bless&lt;&#x2F;strong&gt; or curse?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;compliment&lt;&#x2F;strong&gt; or ridicule?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;save time&lt;&#x2F;strong&gt; or waste time?&lt;&#x2F;li&gt;
&lt;li&gt;to be &lt;strong&gt;generous&lt;&#x2F;strong&gt; or selfish?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;heal&lt;&#x2F;strong&gt; or hurt?&lt;&#x2F;li&gt;
&lt;li&gt;to share &lt;strong&gt;ideas&lt;&#x2F;strong&gt; or focus on self?&lt;&#x2F;li&gt;
&lt;li&gt;to be &lt;strong&gt;open and direct&lt;&#x2F;strong&gt; or talk behind backs?&lt;&#x2F;li&gt;
&lt;li&gt;to focus on things we &lt;strong&gt;can do&lt;&#x2F;strong&gt; or complain about things we have no control over?&lt;&#x2F;li&gt;
&lt;li&gt;to spread &lt;strong&gt;truth&lt;&#x2F;strong&gt; or falsehoods?&lt;&#x2F;li&gt;
&lt;li&gt;to express &lt;strong&gt;thankfulness&lt;&#x2F;strong&gt; or discontent?&lt;&#x2F;li&gt;
&lt;li&gt;to preserve our &lt;strong&gt;autonomy&lt;&#x2F;strong&gt; or be manipulated and exploited by others?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;productive&lt;&#x2F;strong&gt; pursuits or indulgence in vanity?&lt;&#x2F;li&gt;
&lt;li&gt;to engage in &lt;strong&gt;real life&lt;&#x2F;strong&gt; or escape into some virtual universe?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Do we have integrity such that our digital communications match what we would do in person? We live on a great sea of information, and the default path is to be tossed about on the waves of unverifiable communication that wash over our society, and in the end have little to show but discontent and unhappiness. Technology is an excellent tool, but a poor friend, a useful servant, but an oppressive master. Technology is no substitute for the things that bring true joy and satisfaction in life – family, friends, giving, companionship, creativity, craftsmanship, mastery, accomplishment, nature, and faith. Like fire, information technology is only useful when used intentionally and constrained to some useful purpose. Otherwise, it will rob us of our time, relationships, humanity, skills, potential, and ultimately our soul.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Adventures with a ATSAMA5D27 board</title>
        <published>2020-01-29T00:00:00+00:00</published>
        <updated>2020-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1531/adventures-with-a-atsama5d27-board/"/>
        <id>https://bec-systems.com/1531/adventures-with-a-atsama5d27-board/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1531/adventures-with-a-atsama5d27-board/">&lt;p&gt;Recently, we brought up a new PCB (printed circuit board) a customer had designed based on the Microchip &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;wwwproducts&#x2F;en&#x2F;ATSAMA5D27C-D1G&quot;&gt;ATSAMA5D27C-D1G&lt;&#x2F;a&gt; processor. We encountered several interesting challenges.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;trello-attachments.s3.amazonaws.com&#x2F;5c19724d638a035cd3906a52&#x2F;5c6cc390f02bf02ea599cc26&#x2F;309279cce3cf77b7fc5ee79ced947b20&#x2F;image.png&quot; alt=&quot;image.png&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The first issue was that the design only had serial ports (and possibly a USB Host port that could be used in device mode) for bootstrapping the system. Microchip provides a tool named SAM-BA to do this. There are two implementations of SAM-BA. The older implementation does not support this CPU. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atmelcorp&#x2F;sam-ba&quot;&gt;newer implementation&lt;&#x2F;a&gt; does support this CPU, but the documentation and examples are sparse (at least when we were using it). The standard way to use SAM-BA is to directly program the bootstrap and bootloader into SPI flash. However, this design only has eMMC flash. So we came up with a way to bootstrap at91bootstrap and u-boot over the serial port, and then load a Linux kernel with an embedded initramfs from a USB flash disk. This initramfs contains an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;meta-yoe&#x2F;tree&#x2F;master&#x2F;recipes-support&#x2F;updater&#x2F;files&#x2F;sama5d27-som1-ek-sd&quot;&gt;updater&lt;&#x2F;a&gt; that is used to program the eMMC flash. After the updater runs the first time, the system will then boot from eMMC. We developed and verified this process on a development board, and it is documented in a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atmelcorp&#x2F;sam-ba&#x2F;issues&#x2F;39&quot;&gt;Github issue&lt;&#x2F;a&gt; (&lt;em&gt;The SAM-BA team has since disabled Github issues on this repository)&lt;&#x2F;em&gt;, and as part of the Yoe Distro &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;docs&#x2F;sama5d27.md&quot;&gt;sama5d27 support&lt;&#x2F;a&gt;. Microchip has also since provided us with a procedure to program eMMC using SAM-BA, but the procedure is complex and we never had a need for it once we figured out the above method.&lt;&#x2F;p&gt;
&lt;p&gt;After receiving 10 prototypes of the new board, we learned pretty quickly that VCCBU must have voltage for the CPU to start. After that, the first board loaded u-boot and everything looked good, but things went south from there. U-boot would only load perhaps one out of twenty times. Basic checks of power supply voltage levels all looked good. The custom board used a 12MHz crystal for the main clock, where Microchip’s SOM1 module uses a 24MHz crystal. We decided to try a 24MHz crystal, and after that change, u-boot would reliably load over SAM-BA. We’re not sure why (12MHz is slower than 24MHz, so things should run better), but initializing a clock tree is complex and there is likely something that was not configured correctly in software. &lt;strong&gt;Lesson #1: Unless you want to spend a lot of time writing chip initialization software and debugging strange problems, follow a reference design as closely as possible.&lt;&#x2F;strong&gt; Working at the level of chip initialization often requires intimate knowledge of the MPU and likely the support of those who designed the chip. This is much more effort than most teams have time for and is best left to the MPU vendor.&lt;&#x2F;p&gt;
&lt;p&gt;Now that u-boot was loading reliably, we could turn our attention to the kernel. At this point, a couple boards would start the kernel, but most failed with no kernel messages after the “Starting kernel …” message on the serial console. The boards that would start the kernel would crash partway through the boot process. We started looking at power supplies and observed a 100mV sawtooth on the core power supply.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;scope_7-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The SAMA5D27 datasheet specifies a maximum of 15mV of ripple for the core supply.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;core-ripple-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The ADP5023 power supply used for the core voltage had a mode pin that can be used to force it into PWM-only mode, instead of PWS&#x2F;PWM mode. After forcing the supply into PWM-only mode, some boards would start Linux. However, there were still stability problems later in the boot cycle.&lt;&#x2F;p&gt;
&lt;p&gt;After trying many other things, we finally raised the voltage of the core supply slightly by changing one of the feedback resistors. Presto! &lt;strong&gt;Lesson #2: If a CPU has stability problems and everything else looks OK, trying raising the core voltage.&lt;&#x2F;strong&gt; The system was now stable. After communicating with Microchip, we learned that the CPU actually required a higher voltage than the documentation specified. Microchip provides a power supply that is designed to be used with the SAMA5D27 – if this supply would have been used, then we would have gotten the right voltage.&lt;&#x2F;p&gt;
&lt;p&gt;This bringup experience was harder and longer than most – especially for a board of this complexity. But, it illustrates an important point – full custom MPU design is hard – even with a part like the SAMA5D27-D1G which integrates SDRAM in the CPU package. It can require a significant amount of time. This design was done by a competent designer and was extensively reviewed, but it still contained serious problems that took weeks to resolve. In the end, we were still able to make the first PCB revision work with minor modifications. However, it is very possible that the first revision of a PCB like this might need to be scrapped and chalked up to a learning experience leading to months of project delays.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lesson #3: Use a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;System_on_module&quot;&gt;SOM&lt;&#x2F;a&gt; (System on Module) unless you have a good reason to do a full custom design, and you have the time and resources to pull it off.&lt;&#x2F;strong&gt;  You are likely &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.bradfieldcs.com&#x2F;you-are-not-google-84912cf44afb&quot;&gt;not Google or Apple&lt;&#x2F;a&gt;. Yes, you will pay slightly more for a SOM than the raw MPU system components, but the SOM cost may be offset by a lower cost baseboard. A full custom MPU design may require 8 layers and very small routing features where a baseboard for a SOM may only require 4 layers and use larger features, resulting in a less costly PCB. Additionally, a baseboard for a SOM may have a lot less parts on it, and requires less effort to set up for assembly – simpler ones can even be hand built to bypass weeks of assembly lead-time.&lt;&#x2F;p&gt;
&lt;p&gt;There are dozens of SOM vendors offering products today that fit about any price&#x2F;quality&#x2F;certification price point. Some SOMs contain pre-certified WiFi and Bluetooth radios. Others meet various mil-spec requirements. This situation today is much different than 10 years ago when there were only a few expensive SOM models available. SOM modules allow us to bring advanced technology to a problem, and implement a solution with a small team in a reasonable amount of time. Implementing a SOM based MPU design still requires a fair amount of knowledge, but the unknowns are drastically reduced, and chances of success are far better. Much of the design complexity is already handled, freeing you up to work on the value a product provides. Any time we can simplify our development effort, our chances of success are much greater.&lt;&#x2F;p&gt;
&lt;p&gt;Working with Microchip on this project was a good experience. Without their support, we would not likely have resolved the issues we faced in a timely fashion. This brings us to &lt;strong&gt;Lesson #4: When developing complex system, you are likely going to need some level of support.&lt;&#x2F;strong&gt; This may come from IC vendors, open source communities, consultants, etc. In this case, the MPU documentation was not up to date, and the chip designers were able to point out the problem. We could be critical of Microchip for this oversight, but with a 3000+ pages datasheet, this is a lot of detail, and there will be mistakes and oversights. The fact that most of the datasheet is available and accurate is a commendable accomplishment. Getting this level of documentation from some vendors is like pulling teeth. Before any of us cast the first stone, we must ask the question – is everything we do completely and accurately documented? Overall, the SAMA5D27 documentation is pretty good.&lt;&#x2F;p&gt;
&lt;p&gt;The support provided on the SAM-BA Github issues was also essential for us to figure out a way to program the device. The procedure we found for programming this system using only a serial port is relatively simple and easy to implement. Though it may violate some SDRAM refresh timing specs, in practice it works very well – and that is what matters – getting things done. It is unfortunate that Microchip has since closed the Github issues for the SAM-BA project, indicating they are not really interested in building a community around the project, but rather Github is only a way to distribute the tool that is developed in-house. As systems get more complex, Open Source communities are proving to be the only viable mechanism to develop and support all the various needs users might have. Large companies readily acknowledge this as many core technologies are now Open Source, and much effort is put into building communities around them. But, lack of Open Source vision aside, Microchip is a reliable partner – especially for smaller companies wanting to use advanced technology and needing support.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Drone for Continuous Integration</title>
        <published>2019-11-26T00:00:00+00:00</published>
        <updated>2019-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1595/drone-for-continuous-integration/"/>
        <id>https://bec-systems.com/1595/drone-for-continuous-integration/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1595/drone-for-continuous-integration/">&lt;p&gt;Recently, we have been evaluating &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Continuous_integration&quot;&gt;Continuous Integration&lt;&#x2F;a&gt; (CI) systems for a variety of projects (both OSS and customer). There are many OSS &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;community&#x2F;tutorials&#x2F;ci-cd-tools-comparison-jenkins-gitlab-ci-buildbot-drone-and-concourse&quot;&gt;options to chose from&lt;&#x2F;a&gt;. Because we already &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;docs&#x2F;docker.md&quot;&gt;use Docker containers for Yocto&#x2F;OE builds&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;concourse-ci.org&#x2F;&quot;&gt;Concourse&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;drone.io&#x2F;&quot;&gt;Drone&lt;&#x2F;a&gt; made the short list. Both communities seem &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discourse.drone.io&#x2F;t&#x2F;large-20-60gb-cache&#x2F;4676&#x2F;5&quot;&gt;responsive&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discuss.concourse-ci.org&#x2F;t&#x2F;pipeline-for-yocto-bitbake-builds&#x2F;1131&#x2F;8&quot;&gt;helpful&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;figure class=&quot;aligncenter&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;11&#x2F;image-1.png&quot; alt=&quot;&quot;&gt;&lt;figcaption&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&lt;&#x2F;a&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;docs&#x2F;docker.md&quot;&gt;Building OE in a container&lt;&#x2F;a&gt; is important, so naturally Drone and Concourse seem like good options as they are focused on containers. Containers make sense for most CI tasks as they allow you to easily control the environment without getting bogged down in setting up the host. Because Concourse does not seem to easily &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discuss.concourse-ci.org&#x2F;t&#x2F;pipeline-for-yocto-bitbake-builds&#x2F;1131&#x2F;5&quot;&gt;support bind mounting volumes&lt;&#x2F;a&gt; on the host system, we ended up implementing a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;feature-drone&#x2F;.drone.yml&quot;&gt;prototype in Drone&lt;&#x2F;a&gt;. This was improved and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;.drone.yml&quot;&gt;merged&lt;&#x2F;a&gt; into the yoedistro master. Ironically, we are not currently building in a container, as the yoedistro CI machine is a 64-core ARM system and we had some problems with the container support. Hopefully we can get containers working again at some point. Since the initial evaluation, Drone has added an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;exec-runner.docs.drone.io&#x2F;configuration&#x2F;&quot;&gt;exec runner&lt;&#x2F;a&gt;, which allows us to execute a pipeline directly on a machine without a container.&lt;&#x2F;p&gt;
&lt;p&gt;Drone is an excellent fit for most of our projects. There are more capable systems (like Concourse, Jenkins, etc), but the simplicity of Drone is a big advantage in that it will more likely be used by developers. A tool is only useful if it gets used. With Drone, a developer can simply cd to a Git workspace that has a &lt;code&gt;.drone.yml&lt;&#x2F;code&gt; file, and then run &lt;code&gt;drone exec&lt;&#x2F;code&gt; and it will run the entire pipeline locally. Because drone typically does everything in containers, this works fairly well – it does not really matter what the host system is. This is powerful because developers can test the entire pipeline on their local machine before enabling it in the drone server&#x2F;agents for automated testing&#x2F;deployment. If there are problems, they can be debugged locally rather than the tedious process of commit, run the pipeline on the server, view the logs, repeat. Solutions that are simple to use make a big difference in productivity.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a quote from a Drone user:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Today we have over 60 engineers interacting with Drone daily, and they really like it, due to its simplicity. We’ve always had a small DevOps team, so we tend to heavily favor solutions that don’t require a lot of maintenance overhead, and Drone fit the bill. Since most developers have at least a basic understanding of Docker, they hardly need any help maintaining their pipelines, and there have been a couple of instances of developers creating their own plugins! This way our team can focus on exciting upgrades to our infrastructure, even as teams regularly update their deployment pipelines and new projects are created every month.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.drone.io&#x2F;why-quinto-andar-chose-drone&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.drone.io&#x2F;why-quinto-andar-chose-drone&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Drone makes some interesting trade-offs in that it trades some flexibility for simplicity and developer ease of use. Initially, Concourse was my first choice as it is a more powerful tool, but because it does not support bind mounting host volumes or exec runners, we ended up using Drone. This tool makes sense for many teams because it is more likely to be used by the average developer without having a dedicated CI&#x2F;Operations team.&lt;&#x2F;p&gt;
&lt;p&gt;This is a trend we are seeing at successful companies where developers are more responsible for everything related to their project, including testing, continuous integration, deployment, and operations. The quote below gives us some insight into how things are done at Amazon:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is another lesson here: Giving developers operational responsibilities has greatly enhanced the quality of the services, both from a customer and a technology point of view. The traditional model is that you take your software to the wall that separates development and operations, and throw it over and then forget about it. Not at Amazon. You build it, you run it. This brings developers into contact with the day-to-day operation of their software. It also brings them into day-to-day contact with the customer. This customer feedback loop is essential for improving the quality of the service.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;— Werner Vogels (CTO @ Amazon)&lt;&#x2F;strong&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;queue.acm.org&#x2F;detail.cfm?id=1142065&quot;&gt;https:&#x2F;&#x2F;queue.acm.org&#x2F;detail.cfm?id=1142065&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Drone fits into this model well because it enables developers to become engaged in CI and deployment.&lt;&#x2F;p&gt;
&lt;p&gt;One potential problem with drone is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discourse.drone.io&#x2F;t&#x2F;assembla-git-support&#x2F;4694&quot;&gt;lack of support&lt;&#x2F;a&gt; for some Git systems like Assembla. One workaround would be to store pipelines in Github&#x2F;Gitlab&#x2F;Gitea, etc, and then fetch code from other repos. But it would quickly make sense to add auth&#x2F;webhook support for whatever Git system is used if it does not already exist.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reflections on KiCad and EDA Tools</title>
        <published>2019-11-12T00:00:00+00:00</published>
        <updated>2019-11-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1670/reflections-on-kicad-and-eda-tools/"/>
        <id>https://bec-systems.com/1670/reflections-on-kicad-and-eda-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1670/reflections-on-kicad-and-eda-tools/">&lt;p&gt;A &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;blog.snapeda.com&#x2F;2019&#x2F;10&#x2F;28&#x2F;an-interview-with-wayne-stambaugh-of-kicad&#x2F;&quot;&gt;recent interview&lt;&#x2F;a&gt; with a KiCad developer prompted some reflection on KiCad and EDA (electronic design automation) tools in general. Below are samples of several PCB (printed circuit board) designs, created with KiCAD, and implemented as part of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;simpleiot.org&#x2F;&quot;&gt;SimpleIoT project&lt;&#x2F;a&gt; in the last couple months.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;image-6.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;image-4-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The experience has been excellent. Above all, the tool is very fast, efficient to use, and stable. Schematic and PCB integration works well enough, and routing and copper pours are easy. Switching between inches and millimeters can be done on the fly. The KiCad library has many parts in it, and other organizations, such as &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Digi-Key&#x2F;digikey-kicad-library&quot;&gt;DigiKey&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Seeed-Studio&#x2F;OPL_Kicad_Library&quot;&gt;Seeed&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.snapeda.com&#x2F;&quot;&gt;SnapEDA&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ultralibrarian.com&#x2F;&quot;&gt;Ultra Librarian&lt;&#x2F;a&gt; are also providing libraries. If a KiCad symbol&#x2F;footprint for a part is not already available, it is relatively easy to create new symbols and footprints as needed. There is a good KiCad &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;forum.kicad.info&#x2F;&quot;&gt;support forum&lt;&#x2F;a&gt;. KiCad is a pleasure to use and production-ready for standard PCB designs.&lt;&#x2F;p&gt;
&lt;p&gt;Choosing an EDA tool is an investment. There are several aspects to consider:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;purchase&#x2F;licensing cost of the tool&lt;&#x2F;li&gt;
&lt;li&gt;time invested in learning the tool&lt;&#x2F;li&gt;
&lt;li&gt;time spent implementing designs&lt;&#x2F;li&gt;
&lt;li&gt;time spent maintaining designs&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;#2, #3, and #4 swamp #1 for many projects – at least when low end EDA tools are used. Thus we want to be confident that the tool we choose will be around for a while and will be well maintained. With all the churn in the EDA industry in the last 10 years, it is hard to have a lot of confidence in the long term prospects of many tools. For KiCad, however, the development statistics indicate that momentum around the project is increasing and that this tool will likely be around for awhile.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;image-5-1.png&quot; alt=&quot;&quot;&gt;&lt;figcaption&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;KiCad&#x2F;kicad-source-mirror&#x2F;graphs&#x2F;contributors&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;KiCad&#x2F;kicad-source-mirror&#x2F;graphs&#x2F;contributors&lt;&#x2F;a&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;With 183 contributors, the KiCad project appears to be healthy – it is doing something right.&lt;&#x2F;p&gt;
&lt;p&gt;Some may fear that open source projects (like KiCad) are taking away the opportunity for companies to make money and are not sustainable. Has the advent of Linux decreased the amount of money being spent on operating systems? On the contrary, Linux has greatly increased the operating system ecosystem – much more so than if proprietary Unix were the only option. Redhat, Ubuntu, and many other companies seem to be doing well. Linux is used in everything from watches to supercomputers. Unix would never have enabled this breadth of products – it is simply too large a task for any one company or team. Collaboration is the only way to accomplish a project of this magnitude. When the commodity layers are taken care of, then people are free to work on higher level problems. If a commercial EDA tool does about what KiCad does, that product is likely not going to fare well long term. But there is plenty of space to add value higher up the stack. Examples might include tools that work with KiCad such as auto routers, advanced placement tools, library management tools, RF design, SI&#x2F;EMC simulation, high voltage design rules, etc. There is endless opportunity. The “pie” of opportunity is not fixed – it can grow. Contribute code to KiCad that will enable proprietary tools to run in tandem. If companies build on top of KiCad, then they will not have to duplicate the task of building a basic schematic and PCB layout editor and can instead focus on other features, and as a result, there will overall be more value for society. Companies will already have a large market of people who are more likely to spend incremental amounts of money to add functionality as needed. The alternative is for every company to try to provide the entire EDA stack, which can be a tough sell, as it is expensive and customers will need to change everything they are currently doing. There is no reason EDA software cannot become modular like the software development ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;KiCad may displace a few commercial EDA products, but the value and opportunity KiCad will help create will far outweigh this loss. More companies will build more stuff, with less friction and effort. There will be more innovation. More problems will be solved (and likely a few created). There will be more collaboration. Even now, it is practical for developers, who only design PCBs occasionally, to use production grade tools.&lt;&#x2F;p&gt;
&lt;p&gt;EDA tools should not be evaluated merely on technical features and price, but also on the hassle factor, the capability to facilitate collaboration, and the ease of long term product maintenance. Who will maintain your product in two years when a part goes obsolete, the design needs tweaked, and the designer and the obscure tool used on the original design is long gone? If you contract out a PCB design, why not require that the design be implemented using a tool that anyone can use in the future? Part of the value of a product is its maintainability. Companies who can quickly adapt as things change will have an edge. The costs of not being able to quickly respond to some product need, or of having to learn new tools and re-implement a design are significant. Over the life of some products, maintenance costs may be much larger than the initial development costs.&lt;&#x2F;p&gt;
&lt;p&gt;In years past, I’ve used a number of different PCB design tools (Mentor Board Station, OrCad, P-Cad, gEDA, Eagle, etc). Some have been good experiences, others not so much. While there are no doubt EDA tools that have more features and are better than KiCad in some ways, KiCad is the low friction solution for your standard PCB design. It can be used easily by any one at any time on any computer. This flexibility is a big part of KiCad’s value. EDA tools are the “build system” for your hardware. They work best if they are open and easy to use by anyone on the team. There are many “free” PCB design tools available, but few of these are open. Some are cloud based, are very convenient to use, and technically a marvel that we can run a PCB design tool in a browser..  But the design is still locked up in a proprietary format. It is not easy to customize or extend these tools. And the sheer number of these commercial options available today suggests that long term they probably won’t all be around. “Open” is more important than “Free” in my opinion – especially for the long term.&lt;&#x2F;p&gt;
&lt;p&gt;KiCad is certainly a noteworthy project in the technology landscape, and deserves consideration. The availability of such a tool will change the world. The open source hardware movement will grow. Companies who learn to leverage this movement will benefit in the same way that most companies now benefit from the use of open source software. More wealth will be created for society. The traditional barriers between hardware engineers, software developers, and PCB designers will be reduced. Just as hardware engineers have had access to about any software development tool they want to use, now software developers have access to tools to develop and tweak hardware. The small amount of time required to learn KiCad is a worthwhile investment.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Humble Programmer</title>
        <published>2019-10-31T00:00:00+00:00</published>
        <updated>2019-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1646/the-humble-programmer/"/>
        <id>https://bec-systems.com/1646/the-humble-programmer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1646/the-humble-programmer/">&lt;p&gt;In 1972, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Edsger_W._Dijkstra&quot;&gt;Edsger W. Dijkstra&lt;&#x2F;a&gt; published a paper titled &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;~EWD&#x2F;transcriptions&#x2F;EWD03xx&#x2F;EWD340.html&quot;&gt;&lt;em&gt;The Humble Programmer&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. Dijkstra was trained in math and physics and was a university professor for much of his life. This paper is an interesting reflection on the history of computers and contains thoughts for the future. A few quotes are included below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Those who want really reliable software will discover that they must find means of avoiding the majority of bugs to start with, and as a result the programming process will become cheaper. If you want more effective programmers, you will discover that they should not waste their time debugging, they should not introduce the bugs to start with. In other words: both goals point to the same change.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;To put it in another way: as long as machines were the largest item on the budget, the programming profession could get away with its clumsy techniques, but that umbrella will fold rapidly.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Another lesson we should have learned from the recent past is that the development of “richer” or “more powerful” programming languages was a mistake in the sense that these baroque monstrosities, these conglomerations of idiosyncrasies, are really unmanageable, both mechanically and mentally. I see a great future for very systematic and very modest programming languages.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The best way to learn to live with our limitations is to know them. By the time that we are sufficiently modest to try factored solutions only, because the other efforts escape our intellectual grip, we shall do our utmost best to avoid all those interfaces impairing our ability to factor the system in a helpful way.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Dijkstra was 42 years old when we wrote &lt;em&gt;The Humble Programmer&lt;&#x2F;em&gt;. At a similar age of 47 years, I too have come to appreciate the value of simple programming languages and a careful approach to writing software. Two modern languages that embody some of these principles are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elm-lang.org&#x2F;&quot;&gt;Elm&lt;&#x2F;a&gt;. While on the surface these languages may seem very different (one is procedural and one is functional), the values of the languages are similar. Both are designed with a great respect for the finite capability of the human brain. Both strive for simplicity first, and features are only added to the language after careful consideration. Both have excellent tooling that helps ensure consistency and correctness. Both are not just a syntax, but rather a culture and mindset. Experience on recent projects indicates that Go and Elm are effective languages, especially when I compare to previous experiences on C++&#x2F;Javascript projects. There are rarely run-time exceptions. Compiler errors are relatively easy to understand and fix. Tooling is simple and almost invisible. Program maintenance and refactoring is enjoyable.  The combined cognitive load of the language and the tooling is small freeing up resources for solving the problem at hand.&lt;&#x2F;p&gt;
&lt;p&gt;Today, there is a huge amount of churn in the software development world. Especially in front-end development, new frameworks are being released at an astounding rate. Many have their place, and perhaps each addresses some need. But it seems there is something fundamentally wrong with so many solutions for the same problems. Thus, it is encouraging to see new approaches where the authors have carefully studied the past, tried to learn from everything that has been done, and have created solutions where simplicity is valued. This is key to developer effectiveness, and really to life in general.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why are Go applications so reliable?</title>
        <published>2019-10-10T00:00:00+00:00</published>
        <updated>2019-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1625/why-are-go-applications-so-reliable/"/>
        <id>https://bec-systems.com/1625/why-are-go-applications-so-reliable/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1625/why-are-go-applications-so-reliable/">&lt;p&gt;Go does a lot of things well (good performance, easy to learn, very productive, extensive stdlib, excellent tooling, etc), but after programming with Go for three years (both embedded Linux and cloud applications), stability is the characteristic that really stands out.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;go-reliability-1-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;In the past, I’ve observed the development of several fairly large C++ applications. Stability problems were more common than they should have been. Memory leaks, null pointers, crashes, etc. On one project (over 500,000 &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Source_lines_of_code&quot;&gt;SLOC&lt;&#x2F;a&gt;) we built elaborate mechanisms to capture core dumps when things crashed, at times needed to run Gdb on the target system, and spent a fair amount of time in Valgrind tracking down memory leaks. The worst problems were the rare, intermittent ones which only happened in the field and were very difficult to instrument. It is possible to write reliable C&#x2F;C++ code (one example is the Linux kernel), but it takes focused effort (code review, testing, coding standards, etc).  My experience with Javascript has been similar. What if there was a programming language where basic program stability did not have to be a primary concern?&lt;&#x2F;p&gt;
&lt;p&gt;I’ve now participated in four decent-sized Go projects and stability problems are a thing of the past. I only recall one memory leak. Crashes are rare. Several attributes of Go contribute to this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The pattern for returning multiple variables (including error) and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@matryer&#x2F;line-of-sight-in-code-186dd7cdea88&quot;&gt;aligning the happy path to the left&lt;&#x2F;a&gt; encourages error checking before doing anything with the data a function returns. Therefore you don’t end up trying to do things with nil variables. It is a little verbose, but it works and is a small price to pay for the problems it solves.&lt;&#x2F;li&gt;
&lt;li&gt;Garbage collection takes care of memory leaks.&lt;&#x2F;li&gt;
&lt;li&gt;The language encourages simplicity, and simple things are generally more reliable.&lt;&#x2F;li&gt;
&lt;li&gt;The type system catches many errors during compile time.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I’m sure there are others, but these are the ones that stand out to me. Go strikes a nice balance between safety and simplicity. There are safer languages (Rust, Haskell, etc), but they require more effort to learn, and probably require more coding effort (I don’t have a lot of experience, so I could be wrong about this). Every tool has its use and place. If I was developing an application on a space craft going to Mars, I’d probably use Rust. If I am writing a quick script to process some test data, I typically use Python. When writing MCU code, I still use C&#x2F;C++, but someday may use Rust. But when I’m writing a reasonably complex cloud or edge (embedded Linux) application, I use Go. In Go, you can get things done quickly, and be reasonably confident that the application you deploy will not crash or leak memory.&lt;&#x2F;p&gt;
&lt;p&gt;Go’s type system and simplicity require a little more typing than Python, but likely less effort than more complex languages like Rust or Haskell. Go is a pragmatic language that gets you 98% there without a lot of overhead. In business, you generally don’t want to add a lot of process overhead on the entire company for the 2% of people who may be causing problems, as it imposes drag on the other 98% trying to get things done. Rather, it makes sense to address the 2% at a personal level. Likewise, with Go, the 2% of the time you have to fix a nil bug, or a unhandled case the type system did not catch, is acceptable as 98% of the time you are working in a language that is very productive with very little overhead. Go is ideal for many applications.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Auto-formatting&#x2F;linting Go code</title>
        <published>2019-04-22T00:00:00+00:00</published>
        <updated>2019-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1581/auto-formatting-linting-go-code/"/>
        <id>https://bec-systems.com/1581/auto-formatting-linting-go-code/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1581/auto-formatting-linting-go-code/">&lt;p&gt;Some things in life you just have to experience to truly appreciate the value. One of these is auto-formatting&#x2F;linting source code. When I started programming in Go in Vim, I naturally looked for editor support, and found the excellent &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fatih&#x2F;vim-go&quot;&gt;vim-go&lt;&#x2F;a&gt; project. Through this, I learned about &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;cmd&#x2F;gofmt&#x2F;&quot;&gt;gofmt&lt;&#x2F;a&gt;and then &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;godoc.org&#x2F;golang.org&#x2F;x&#x2F;tools&#x2F;cmd&#x2F;goimports&quot;&gt;goimports&lt;&#x2F;a&gt;. These tools can be configured in your editor to automatically format your code when you save. goimports goes a step beyond and adds missing imports and removes unused ones.&lt;&#x2F;p&gt;
&lt;p&gt;Auto-formatting is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@ryconoclast&#x2F;why-you-should-use-a-code-formatter-4f02dd40db14&quot;&gt;quickly&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@jtomaszewski&#x2F;keep-your-code-clean-forever-65c71f7f2df&quot;&gt;becoming&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.freecodecamp.org&#x2F;why-robots-should-format-our-code-159fd06d17f7&quot;&gt;the&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.freecodecamp.org&#x2F;here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a&quot;&gt;norm&lt;&#x2F;a&gt;. The Javascript world also has an excellent formatter available named &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;prettier.io&#x2F;&quot;&gt;Prettier&lt;&#x2F;a&gt;. There are formatters for many other languages as well including &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;clang.llvm.org&#x2F;docs&#x2F;ClangFormat.html&quot;&gt;C&#x2F;C++&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mvdan&#x2F;sh&quot;&gt;shell&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;avh4&#x2F;elm-format&quot;&gt;Elm&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rustfmt&quot;&gt;Rust&lt;&#x2F;a&gt;, etc. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sbdchd&#x2F;neoformat&quot;&gt;neoformat&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;w0rp&#x2F;ale&quot;&gt;ALE&lt;&#x2F;a&gt; plugins add auto-formatting functionality to Vim&#x2F;Neovim. An example of how to enable these plugins in Neovim is included in my &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;dotfiles&#x2F;blob&#x2F;master&#x2F;nvim&#x2F;.config&#x2F;nvim&#x2F;init.vim&quot;&gt;dotfiles&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Below are instructions on how to set up &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;code.visualstudio.com&#x2F;&quot;&gt;Visual Studio Code&lt;&#x2F;a&gt; to auto-format code. Even though I use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;neovim.io&#x2F;&quot;&gt;Neovim&lt;&#x2F;a&gt; for most of my code editing, I still try out VS code and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;idea&#x2F;&quot;&gt;IntelliJ IDEA&lt;&#x2F;a&gt; from time to time to learn what’s new in cutting-edge editors. I also recommend VS Code for most new Go developers – especially those coming from embedded systems development where an IDE is traditionally used. Give it a try – it will only take you a few minutes.&lt;&#x2F;p&gt;
&lt;p&gt;The instructions below should work with most systems (Windows, Linux,  Mac). First, make sure Go and VS code are installed. Then install the Go VS code extension.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-1-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Next, type Ctrl-Shift-P to bring up the command palette and run Go:  Install&#x2F;Update Tools.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-2-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;This will display a list of tools – select them all.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-3-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Next, configure VS Code to format on save. Open the settings by selecting File-&amp;gt;Preferences-&amp;gt;Settings from the menu. Select the “Format on Save” option and set the timeout to something larger than the default, like 5000ms.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-4-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Last, select goimports as the code formatting tool – this will automatically manage the imports in your file, as well as formatting the code.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-5-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Now, open a Go source file. Mess up the formatting of some code and then save – the code should be automatically formatted. Similarly, if you remove one of the import statements that is being used, and save, the imports will be corrected. Unused imports will be removed.&lt;&#x2F;p&gt;
&lt;p&gt;These tools allow you to focus on writing software and let the tools worry about formatting and imports. Prettier code with less effort – why not?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Microcontroller (MCU) or Microprocessor (MPU)?</title>
        <published>2019-04-09T00:00:00+00:00</published>
        <updated>2019-04-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1540/microcontroller-mcu-or-microprocessor-mpu/"/>
        <id>https://bec-systems.com/1540/microcontroller-mcu-or-microprocessor-mpu/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1540/microcontroller-mcu-or-microprocessor-mpu/">&lt;p&gt;As technology advances, there are two basic processing platforms for implementing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Embedded_system&quot;&gt;embedded systems&lt;&#x2F;a&gt;. The first is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Microcontroller&quot;&gt;Microcontroller Unit&lt;&#x2F;a&gt; (MCU). These devices have varying amounts of integrated Flash (&amp;lt;= 2MB) and RAM (&amp;lt;= 1MB), and are designed to run bare-metal code or a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Real-time_operating_system&quot;&gt;real-time operating system&lt;&#x2F;a&gt; (RTOS), like FreeRTOS. The second is the Linux-capable &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;w&#x2F;index.php?title=Microprocessor_unit&amp;amp;redirect=no&quot;&gt;Microprocessor Unit&lt;&#x2F;a&gt; (MPU).  An example of an MCU based system is most Arduinos, and an example of an MPU based system is the Raspberry PI. An MPU typically does not have embedded Flash and RAM – at least on the same die. The fundamental difference between MCU&#x2F;RTOS and MPU&#x2F;Linux systems is the memory architecture and the amount of memory in the system.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;mcu-vs-mpu-3-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There are other differences as well, summarized in the table below.&lt;&#x2F;p&gt;
&lt;table class=&quot;wp-block-table aligncenter has-fixed-layout is-style-stripes&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Feature&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;MCU&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;MPU&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;# power supplies&lt;&#x2F;td&gt;&lt;td&gt; 3.3V&lt;&#x2F;td&gt;&lt;td&gt;VCORE, VIO, VDDR, etc.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;USB Host&lt;&#x2F;td&gt;&lt;td&gt;limited&lt;&#x2F;td&gt;&lt;td&gt;Full support &lt;br&gt;many drivers&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Networking&lt;&#x2F;td&gt;&lt;td&gt;limited&lt;&#x2F;td&gt;&lt;td&gt;Options for GB and&lt;br&gt;multiple interfaces&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Cost&lt;&#x2F;td&gt;&lt;td&gt;lower&lt;br&gt;$1-$20&lt;&#x2F;td&gt;&lt;td&gt;higher, starts at&lt;br&gt;$10 (cpu + power&#x2F;mem)&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Programming&lt;br&gt;Languages&lt;&#x2F;td&gt;&lt;td&gt;C&#x2F;C++&lt;br&gt;Micropython&lt;br&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;C&#x2F;C++, Go, Python, Nodejs, &lt;br&gt;Java, Erlang, Rust,&lt;br&gt;about anything&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Realtime&lt;&#x2F;td&gt;&lt;td&gt;hard&lt;&#x2F;td&gt;&lt;td&gt;soft&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Data processing&lt;&#x2F;td&gt;&lt;td&gt;limited&lt;&#x2F;td&gt;&lt;td&gt;excellent&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Processing power&lt;&#x2F;td&gt;&lt;td&gt;less&lt;&#x2F;td&gt;&lt;td&gt;more&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Display size&lt;&#x2F;td&gt;&lt;td&gt;small&lt;&#x2F;td&gt;&lt;td&gt;any size&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Startup time&lt;&#x2F;td&gt;&lt;td&gt;fast&lt;&#x2F;td&gt;&lt;td&gt;slow&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Expandable over&lt;br&gt;time&lt;&#x2F;td&gt;&lt;td&gt;less so&lt;&#x2F;td&gt;&lt;td&gt;more so&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;On-chip&lt;br&gt;Peripherals&lt;&#x2F;td&gt;&lt;td&gt;more&lt;br&gt;&lt;&#x2F;td&gt;&lt;td&gt;less&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;PCB real-estate&lt;&#x2F;td&gt;&lt;td&gt;less&lt;&#x2F;td&gt;&lt;td&gt;more (external flash&#x2F;RAM)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Performance is related to memory architecture. In most MCUs, the memory architecture is fairly simple. Code is executed directly from flash, and on-chip SRAM is accessed directly. Programs do not need to be loaded from flash into RAM before running them. This architecture is very simple, leading to predictable real-time response and code execution. It takes a consistent amount of time to load code from flash into the processor for execution, so the timing for every instruction is fairly predictable. However, with this architecture, clock rate is typically limited to around 190MHz (example STM32F4). Some of the newer STM32 parts, such as the STM32F7 and STM32H7, add a L1 cache, which allows the CPU to run at 216MHz and 400MHz respectively.&lt;&#x2F;p&gt;
&lt;p&gt;MPUs have a more complex memory architecture in that they page code from Flash into SDRAM (both external to the MPU), and then from SDRAM into two or more levels of cache memory located on the MPU. The local cache memory is very fast, allowing these processors to run at high clock rates (1GHz or more in some cases). A &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Memory_management_unit&quot;&gt;memory management unit&lt;&#x2F;a&gt; (MMU) implements a virtual memory system in which physical pages from RAM are mapped into a virtual address space. This is very efficient as physical pages are only mapped in as needed and can be discarded if RAM is needed elsewhere. But this memory management introduces delays that are relatively long for some hard real-time systems. The first access to a block of code that has not been run recently takes time, as code needs to be paged from a file in flash into SDRAM and then loaded into the respective caches. But subsequent accesses from cache are blazing fast. An MMU also provides protection against one user space process corrupting memory of another process, or corrupting kernel memory. For complex systems (server&#x2F;desktop) running multiple processes, this protection increases the system reliability. For many Embedded systems, there is only one main application, and protecting processes from each other is less of a concern. However, this memory protection is still useful in that a bug in the application does not crash the system, and recovery mechanisms can be built in to restart the app, or debug it during development.&lt;&#x2F;p&gt;
&lt;p&gt;In an MCU, program flow is controlled through simple loops and state machines (no operating system) or a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Real-time_operating_system&quot;&gt;real-time operating system&lt;&#x2F;a&gt; (RTOS). In an MPU system, a fairly complex operating system like Linux is typically required to manage the multiple levels of memory and storage, schedule the multiple processes that are running, and provide drivers for the complex hardware systems found in an MPU (USB, large displays, networking, etc). There is a great gulf between these two systems. Even though a RTOS may run on an MPU, there are much longer delays in execution due to the memory architecture. You still have to load code from flash to SDRAM and then through several layers of cache memory before the CPU can execute it. Once it is in cache, the code executes much faster and can do more work overall, but the occasional delays are still there. You might be able to play tricks by locking lines of code in cache or by using the small amount of on chip SRAM that may be present, but by the time you do this, you are now back to the smaller memory sizes on an MCU, and may as well just use an MCU.&lt;&#x2F;p&gt;
&lt;p&gt;After understanding the differences in memory architectures, we can understand that MCUs and MPUs are optimized for different things. An MCU is optimized for simplicity, cost, and predictable (real-time) response times. An MPU is optimized for getting the maximum amount of work done over time. Cost and real-time response is a secondary concern. There is not really a lot of middle ground between an MCU and MPU, evidenced by the large gap in memory sizes. You can’t fit standard Linux in an MCU, as there is only so much NOR Flash and SRAM that will fit on an MCU die. Once you move to more dense memory technologies such as NAND Flash and SDRAM, these must be implemented as separate dies and typically separate integrated circuit packages. These technologies are so efficient at storing large amounts of data, that you see a huge jump in memory capacity once you switch to the off-chip memories.&lt;&#x2F;p&gt;
&lt;p&gt;MCUs and MPUs also have different origins. Today’s 32-bit MCUs have descended from simpler 8-bit MCUs and are scaled-up embedded controller technologies. MPUs have descended from desktop and server computer systems and are scaled-down technologies. The differing priorities of these two paradigms reflect their different uses.&lt;&#x2F;p&gt;
&lt;p&gt;Keeping these differences in mind, the most fundamental question to ask in selecting an MCU or an MPU is whether hard real-time performance and reliability is most critical (&lt;strong&gt;control-centric application&lt;&#x2F;strong&gt;), or whether data processing performance and connectivity is most important (&lt;strong&gt;data-centric application&lt;&#x2F;strong&gt;). If both of these are important in your application, you should consider having both an MCU and MPU in the system, saving yourself untold pain.&lt;&#x2F;p&gt;
&lt;p&gt;Reliability is an interesting topic. I have seen MPU&#x2F;Linux systems operate very reliably, and have also experienced issues that were very difficult to solve. MPU systems are many times more complex and have more unknowns, which translates into more risk. There are many more physical components and solder connections required to implement the system, all of which can fail over time with environmental stress. There are many millions of lines of code in an MPU system that you did not write, but you are still responsible for all of it – it all has to work for the system to function. Although an MPU system can be made fairly reliable, simple statistics tell us that MCUs will generally be more reliable than an MPU because there is less hardware that can fail and less lines of code running that may contain bugs.&lt;&#x2F;p&gt;
&lt;p&gt;One example of a problem we experienced when implementing control in an MPU system is a product where we were collecting data, and the data was being transferred back to a cloud server over a cellular modem. Unfortunately, the cellular modem in the system was not 100% reliable, and the only way to recover in some instances was to reboot the system when we detected a network failure, which cycled power to the modem (this modem module itself ran Linux). At one point, we added some basic control functionality to the system to control plant blowers based on a schedule. The control worked fine until the system had to restart due to modem connectivity issues, then the blower control was inactive during the reboot cycle (perhaps 30s or so). This was not a fatal problem in this application but also not ideal. The obvious solution is to get a more reliable modem or develop a better recovery method, but with units in the field and other development priorities, it is not always so simple. This is a classic example of the tension between complex data&#x2F;connectivity systems and reliable control.&lt;&#x2F;p&gt;
&lt;p&gt;In an MCU system, the hardware system is relatively simple, and you are using a relatively small RTOS, or none at all. You write a greater percentage of the code in the system yourself, so if you have a simple task to do, and write reliable code, there is a potential to have a more reliable system than a comparable MPU system. However, if you are trying to do complex data processing and connectivity tasks on an MCU (such as writing your own database, network, or USB stack), chances are there will be bugs in your code and you will have a less reliable system than if you would have chosen an MPU using proven technologies. If your application is large and complex, then writing it in a safer language like Go or Rust on an MPU may provide a more reliable and maintainable product than trying to implement the same functionality in C++. Again, if you need both reliable real-time control and advanced data processing, then put both an MPU and MCU in the system.&lt;&#x2F;p&gt;
&lt;p&gt;Another advantage of an MPU system is they tend to be more general purpose and more functionality can be added over time. There is little danger of running out of code space, which often happens in MCU environments. With interfaces like USB, additional peripherals can be added in the future as requirements change, and with Linux, drivers for a vast array of hardware are available.&lt;&#x2F;p&gt;
&lt;p&gt;In some cases these lines between MCUs and MPUs are blurred by technologies like Linux RT extensions, or uCLinux, but you still must keep the above principles in mind when selecting the building blocks for your product. MCUs and MPUs are very different devices designed to handle different tasks. Before choosing, you should understand what you are trying to do, and what is important for your product.&lt;&#x2F;p&gt;
&lt;p&gt;Reference:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ww1.microchip.com&#x2F;downloads&#x2F;en&#x2F;DeviceDoc&#x2F;MCU_vs_MPU_Article.pdf&quot;&gt;Atmel MCU vs MPU paper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.st.com&#x2F;b&#x2F;en&#x2F;microcontrollers-microprocessors.html&quot;&gt;ST page referencing both MCU and MPU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Accepting Constraints in Build Systems</title>
        <published>2019-04-01T00:00:00+00:00</published>
        <updated>2019-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1462/accepting-constraints-in-build-systems/"/>
        <id>https://bec-systems.com/1462/accepting-constraints-in-build-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1462/accepting-constraints-in-build-systems/">&lt;p&gt;As Embedded Systems become more complex, the complexity of the process to build the software for these systems also increases. As humans, our ability to deal with complexity is limited, so we develop &lt;strong&gt;tools and processes&lt;&#x2F;strong&gt; to manage the complexity. In the end, these tools and processes are about &lt;strong&gt;constraints and patterns&lt;&#x2F;strong&gt;. A well-designed tool or process encourages you to do things in a way that is &lt;strong&gt;consistent and maintainable&lt;&#x2F;strong&gt;, which leads to &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt; results.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;reliable-and-predictable-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;As an example, consider using CMake vs standard Makefiles for a C++ application build system. This is a trade-off I often encounter, as my customers are using Linux to build products, and they need to develop a relatively complex software application to implement the product functionality. There are usually a handful of library dependencies as well (such as Qt, OpenCV, etc) – after all, the reason you use Linux is it provides a large amount of advanced functionality that you cannot afford to write yourself.&lt;&#x2F;p&gt;
&lt;p&gt;For a simple application, CMake is somewhat constraining and annoying. Its syntax is a little clumsy, and it is definitely less flexible than a Makefile. Thus some developers conclude that a Makefile is a better choice for Linux application builds. As the application grows, the Makefile also grows, and the number of dependencies increases. Then comes the time to cross compile the application so it will run on the target system. With a little work, we can convince the Makefile to accomplish this. Tool-chain file names and paths are often hard-coded in the Makefile. As the variations of systems the application needs to build on increase, all these variations are coded in the Makefile.&lt;&#x2F;p&gt;
&lt;p&gt;Five years down the road, something major changes. The application developers need some new features in a new version of OpenCV, or the System on Module (SOM) the target system is using just went obsolete. The developer who wrote the original Makefiles is gone. The Linux host distributions have changed. At this point the application build system collapses. So much has changed, and so much is hard coded in the Makefiles that getting them working again is a painful and tedious process. With some effort, they are finally building on one developer’s machine. But on the next developer’s machine, they fail with a different error.&lt;&#x2F;p&gt;
&lt;p&gt;The same dynamic happens when developers hack together tools to build an operating system image for an embedded device. This typically involves things like building the application or Linux kernel manually outside the build system, then writing a script to unpack an image file, insert the new binary, then pack the image file back up. The application build process is heavily dependent on the configuration of the developer’s workstation.&lt;&#x2F;p&gt;
&lt;p&gt;There is a better way. Use tools like Yocto&#x2F;OpenEmbedded and CMake as they are were meant to be used. These tools do have a learning curve, and require some investment to learn, but in the end they are well worth it. The reason tools like OpenEmbedded and CMake work is that they are consistent, and use the same patterns over and over. We can illustrate the basic architecture of OpenEmbedded in a simple sketch, as shown below. OpenEmbedded is made up of a relatively small number of primitives:&lt;em&gt;layers, recipes, packages, classes,&lt;&#x2F;em&gt; &lt;em&gt;conf files, and tasks&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;oe-architecture-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Dependencies can be specified at the layer, recipe, package, and task level. Once these basic concepts are understood, then it is easy to find things in the build system and make necessary modifications. The boundaries are precise and well-defined. These patterns are not as flexible as a Makefile or Bash script, but they abstract huge amounts of complexity. This allows our mind to see the big picture and not get bogged down in thousands of details and to reliably execute extremely complex tasks. The same patterns are used over and over and are easy to recognize. Dependencies are well-controlled. The cost is to understand and use the established &lt;strong&gt;patterns&lt;&#x2F;strong&gt; and to accept the &lt;strong&gt;constraints&lt;&#x2F;strong&gt;. These constraints may be a little inconvenient at times. But when you compare this to the work these tools do for you, these inconveniences are relatively minor.&lt;&#x2F;p&gt;
&lt;p&gt;If you are going to build complex products using complex technologies like Linux, then you need powerful tools to manage this complexity. There is a learning curve. You may need to invest in training or hire someone to help you get started. Most other industries recognize this. Car mechanics undergo continuous training to learn how to work on new vehicles&#x2F;systems. Nurses and other professionals receive training on new techniques and equipment.  Build systems also require a significant investment in learning. We routinely hire experts (doctors, dentists, plumbers, carpenters, etc) in our personal lives to do things we don’t know how or have time to do. But somehow many developers think the build system and associated infrastructure should not need attention, can be ignored, or is trivial and can be implemented from scratch. Never mind the fact that the underlying software in the system (bootloader, kernel, and libraries) are many times more complex than the custom application software written for the system. You must be able to &lt;strong&gt;maintain&lt;&#x2F;strong&gt; it all. You can’t ignore the stuff you did not write – it all has to work. It has to be &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt;.  A build system is largely invisible until it starts causing problems.&lt;&#x2F;p&gt;
&lt;p&gt;Getting something working initially is relatively easy; keeping it working for years is another matter. It is similar to product development – building the first prototype that somewhat works often goes fairly quick. Getting something into production is a long, arduous slog. The build system is the foundation of your software project. It must be &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt; because you can’t do much without it. A build system must do its part well without a lot of fuss, so we can focus on the problem being solved. A well implemented build system produces an image ready for installation with a single command and no manual steps. You check source code into git, run the build command, and out pops an image ready to deploy. There is no copying around binaries, etc. The efficiency gained by the effort to implement such a system pays itself back many times over the life of a project – especially those that are produced for 5-10 years.&lt;&#x2F;p&gt;
&lt;p&gt;Yocto and CMake are only used as examples in this article and may not be the best solution for every project. If you have something that is working well, keep doing what you are doing. But if what you are doing is not working, then ask yourself some  questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Is my current system the best way to build complex software?&lt;&#x2F;li&gt;
&lt;li&gt;Is the &lt;strong&gt;process&lt;&#x2F;strong&gt; to build your project’s software simple and easy to reproduce by any developer on any machine?&lt;&#x2F;li&gt;
&lt;li&gt;Is it well documented?&lt;&#x2F;li&gt;
&lt;li&gt;Is it &lt;strong&gt;maintainable&lt;&#x2F;strong&gt;?&lt;&#x2F;li&gt;
&lt;li&gt;Is it &lt;strong&gt;consistent&lt;&#x2F;strong&gt; across all your products?&lt;&#x2F;li&gt;
&lt;li&gt;Is it &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt;?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SD Card Write Speed Tests</title>
        <published>2019-03-13T00:00:00+00:00</published>
        <updated>2019-03-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1465/sd-card-write-speed-tests/"/>
        <id>https://bec-systems.com/1465/sd-card-write-speed-tests/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1465/sd-card-write-speed-tests/">&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;IMG_20190313_084412667-1.jpg&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;During Embedded Linux development, we often need to write large operating system images to SD cards for testing. Recently, I purchased a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;plugable.com&#x2F;products&#x2F;usb3-flash3&#x2F;&quot;&gt;USB 3.0 SD card reader&lt;&#x2F;a&gt; from Plugable. Before that, I used a USB 2.0 SD card reader from IOGear.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;IMG_20190313_084233773-1.jpg&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;How much better does a USB 3.0 card reader perform compared to a 2.0 card reader? To test, I wrote a large (2.2GB) image to a Transcend v30 card using both readers.&lt;&#x2F;p&gt;
&lt;table class=&quot;wp-block-table has-fixed-layout is-style-stripes&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;IO Gear USB 2.0 Reader&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Plugable USB 3.0 Reader&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15.3 MB&#x2F;s&lt;&#x2F;td&gt;&lt;td&gt;33.5 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The USB 3.0 reader is over twice as fast with this same card!&lt;&#x2F;p&gt;
&lt;p&gt;I then used the USB 3.0 reader to compare a number of cards.&lt;&#x2F;p&gt;
&lt;table class=&quot;wp-block-table has-fixed-layout is-style-stripes&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SD Card Brand&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Size&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Grade&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Tested&lt;br&gt;Speed&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Transcend&lt;&#x2F;td&gt;&lt;td&gt;8GB&lt;&#x2F;td&gt;&lt;td&gt;C10 HC&lt;&#x2F;td&gt;&lt;td&gt;8.8 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Sandisk&lt;&#x2F;td&gt;&lt;td&gt;32GB&lt;&#x2F;td&gt;&lt;td&gt;C10 HC I&lt;&#x2F;td&gt;&lt;td&gt;16.8 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Transcend&lt;&#x2F;td&gt;&lt;td&gt;16GB&lt;&#x2F;td&gt;&lt;td&gt;C10 HC I V30&lt;&#x2F;td&gt;&lt;td&gt;33.5 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Sandisk&lt;&#x2F;td&gt;&lt;td&gt;64GB&lt;&#x2F;td&gt;&lt;td&gt;XC I V30 A1&lt;&#x2F;td&gt;&lt;td&gt;44.5 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The markings on the cards mean various things. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SD_card&quot;&gt;Wikipedia SD Card page&lt;&#x2F;a&gt; provides a nice overview. A few details are summarized below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bus interface&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I: 50MB&#x2F;s Half&#x2F;Full duplex, 104MB&#x2F;s Half Duplex&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Capacity&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;HC: Secure Digital High Capacity (SDHC) format – supports cards 2GB to 32GB in size&lt;&#x2F;li&gt;
&lt;li&gt;XC: Secure Digital eXtended Capacity (SDXC) format – supports cards 32GB to 2TB in size&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Speed&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;10 with C around it: Minimal sequential writing speed is 10 MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;3 with U around it: UHS Speed Class: 30MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;V30: Video Speed Class: 30MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;A1: Application Performance Class 1: Read 1500 IOPS, Write 500 IOPS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you have not upgraded to a USB 3.0 card reader, it is probably worth your time to do so.&lt;&#x2F;p&gt;
&lt;p&gt;One note of caution – there are counterfeit cards for sale that look like SanDisk or Transcend cards.  They are not manufactured by these companies, and use lower quality components. If the price seems too good to be true, it probably is. Always buy from a reputable supplier.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting started with Embedded Linux</title>
        <published>2018-10-04T00:00:00+00:00</published>
        <updated>2018-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1154/getting-started-with-embedded-linux/"/>
        <id>https://bec-systems.com/1154/getting-started-with-embedded-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1154/getting-started-with-embedded-linux/">&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2018&#x2F;09&#x2F;embedded-linux-2.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Recently I was asked by a developer, who has done windows development for 10 years, how to get started with Embedded Linux. Embedded Linux covers a lot of ground and includes a broad range of components&#x2F;skills to put together an entire system. Below are a few suggestions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;do-i-have-the-right-mindset&quot;&gt;Do I have the right Mindset?&lt;&#x2F;h3&gt;
&lt;p&gt;There are many different types of people; there are those who are who are a good fit for Linux, and those who are not. There are those who think Open Source Software (OSS) and Linux are the craziest thing they ever heard of, and those who think it’s a great idea. There are those who thrive on openness and collaboration, and those who feel threatened by it. A few specific aspects of this mindset are described below.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;code-gardening&quot;&gt;Code Gardening&lt;&#x2F;h4&gt;
&lt;p&gt;Much of your time as an embedded Linux developer is spent figuring stuff out (vs writing new code). Figuring out stuff is harder than writing new code (at least initially). It is similar to weeding the garden – often not something you are raring to do, but after you are finished, it feels really good. Much of the truly valuable work in life is like this. It initially appears kind of boring, but once you get started there are many interesting and rewarding aspects.&lt;&#x2F;p&gt;
&lt;p&gt;You have to like build systems and automation. Linux systems are complex. You can’t throw millions of lines of kernel and user space code together with a simple Makefile or a fancy IDE. Proficiency with command line tools is required. Builds must be clean and completely automated if you want to keep your sanity. Once you allow one manual step in the build, the floodgate has been opened, and these manual steps will start to accumulate at a frightening pace until you have an unmaintainable mess.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;collaboration&quot;&gt;Collaboration&lt;&#x2F;h4&gt;
&lt;p&gt;Because of the complexity, you have to be able to collaborate with others. This requires a generous mindset. How can I make this easy for someone else to pick up once I am gone? Most likely this someone will be you in a couple months or years when you have forgotten many of the project details. The same really applies to coding. Do I write my code to be clever, do I hack it together, or do I focus on making it maintainable and easily understand by others? Automation and simplicity reduce cognitive load, freeing up resources to think about the problems that actually need solved, and allow multiple people to work on a project without a lot of friction.&lt;&#x2F;p&gt;
&lt;p&gt;The flip side of this is humility. With a complex system like Linux, there will be a lot of things you don’t know, and some difficult problems to solve. There is no one “manual” for Linux where you can go look up an answer. So we rely on open source communities for help. There are many people willing to help, so the key is to have the wisdom to know where and when to ask for help, and then the humility to ask. In Linux communities (and OSS in general), you will be surrounded by developers who are much smarter and more knowledgeable than you. At the very least, there will always be someone who knows something you don’t. If you don’t have the humility to acknowledge this and be willing to learn, then you will likely never be comfortable or effective working in an OSS environment.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;nih&quot;&gt;NiH&lt;&#x2F;h4&gt;
&lt;p&gt;This can all be a challenge for developers who are endowed with a healthy dose of NiH (Not Invented Here Syndrome). These are people who imagine themselves happiest writing and maintaining their own code, and who are not inclined to share it with others. Some imagine themselves as great software architects and coders (very few of us really are) who can make something better. They don’t want to spend long, arduous hours learning and debugging a complex system written by someone else. If this describes you, then perhaps Embedded Linux is not for you.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;learning&quot;&gt;Learning&lt;&#x2F;h4&gt;
&lt;p&gt;Are you a learner? Do you enjoy learning about new technology, tools, techniques, etc? Everything is always changing in the Linux world. New and compelling solutions are coming out every year. The real power of Linux and Open Source is knowing when and how to leverage these new technologies to solve real problems. If you are more comfortable doing things the way they have always been done, then perhaps you should just keep doing what you are doing.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-problem-of-abundance&quot;&gt;The Problem of Abundance&lt;&#x2F;h4&gt;
&lt;p&gt;Can you deal with a lot of choices? With Embedded Linux, there are many options for about every aspect of the system. There are multiple init systems. There are many programming languages. There are many libraries available for various tasks. There is no one, true way to implement Embedded Linux – you will have to make a lot of choices.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ideas-for-learning-embedded-linux&quot;&gt;Ideas for Learning Embedded Linux&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;books-presentations-documentation-blogs&quot;&gt;Books&#x2F;Presentations&#x2F;Documentation&#x2F;Blogs&lt;&#x2F;h4&gt;
&lt;p&gt;There are many books published on Linux, Embedded Linux, Yocto, etc. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;&quot;&gt;Yocto documentation&lt;&#x2F;a&gt; is pretty good. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLbzoR-pLrL6qAnHzPdrTxwCUWPja5KnOq&quot;&gt;Videos from the Embedded Linux Conference&lt;&#x2F;a&gt; are freely available. There are many blogs that cover Embedded Linux topics (such as this one). Subscribing to blog RSS feeds in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;feedly.com&quot;&gt;feedly&lt;&#x2F;a&gt; is a good way to keep up with recent developments.&lt;&#x2F;p&gt;
&lt;p&gt;The list of learning resources is endless, but perhaps the key thing to remember is there is no one place you can go to learn everything you need to know, like you might for a commercial RTOS. The good news is there is information available in many different formats, so you can choose what best fits your learning style.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;run-linux-on-your-computers&quot;&gt;Run Linux on your computers&lt;&#x2F;h4&gt;
&lt;p&gt;One of the best ways to learn a lot about Linux is to simply use it for your personal and work computers. Ubuntu is very easy to get started with. If you go with something like Arch Linux, the install process will teach you a lot. I am very pleased with the combination of Arch Linux plus the XFCE desktop environment. This is a no-nonsense setup that does its job well, is very customizable, and stays out of my way. Any distribution will work – just pick something.&lt;&#x2F;p&gt;
&lt;p&gt;Embedded Linux aside, there is little to lose, and a lot to gain from running Linux. Linux systems are naturally much more immune to viruses, malware, and various other attacks than Windows. Linux systems are much more flexible than Apple computers. Some things might not look as pretty, or might take a little more work to set up. But the stability, flexibility, and consistency of a Linux system will save you time in the long run. As a software developer, most of our time is spent in an editor and browser – these work very well in Linux. Additionally, the terminal is a first class citizen in Linux rather than an afterthought.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;learn-git&quot;&gt;Learn Git&lt;&#x2F;h4&gt;
&lt;p&gt;Git is used in almost all open source projects these days, and enables new levels of collaboration. You &lt;a href=&quot;&#x2F;723&#x2F;why-git&#x2F;&quot;&gt;need to know Git&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;do-small-projects-with-raspberry-pi-etc&quot;&gt;Do small projects with Raspberry PI, etc.&lt;&#x2F;h4&gt;
&lt;p&gt;There are a number of embedded computer boards out there that are very well supported and quite cheap such as the Raspberry PI. Find something in your home that you want to automate – there’s nothing like a real project to motivate learning. With Linux, you learn best by doing. This will also give you an opportunity to learn application programming under Linux.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;build-and-install-openembedded-yocto-or-buildroot&quot;&gt;Build and install OpenEmbedded&#x2F;Yocto or Buildroot&lt;&#x2F;h4&gt;
&lt;p&gt;Take the previously discussed home automation project and create a custom build for the board using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.yoctoproject.org&#x2F;&quot;&gt;Yocto&#x2F;OE&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;buildroot.org&#x2F;&quot;&gt;Buildroot&lt;&#x2F;a&gt;. This will give you practice learning how to put together a custom embedded Linux distribution. Create recipes to package, and include your custom applications in the image at build time (instead of installing them afterwards).&lt;&#x2F;p&gt;
&lt;p&gt;These tools have a learning curve and may seem intimidating initially, but Linux is a complex system, and you need powerful tools.&lt;&#x2F;p&gt;
&lt;p&gt;We think the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&quot;&gt;BEC OE template&lt;&#x2F;a&gt; (now &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&quot;&gt;yoe-distro&lt;&#x2F;a&gt;) is a good way to set up Yocto&#x2F;OE for a project.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;modify-the-linux-kernel&quot;&gt;Modify the Linux Kernel&lt;&#x2F;h4&gt;
&lt;p&gt;Most embedded Linux projects require a small amount of kernel modification. This can be something as simple as changing the GPIO configuration on an ARM SOC (System on chip), or writing a driver for some custom hardware. There are many resources available for learning Linux kernel programming. Perhaps try creating a custom driver for your PC or embedded Linux board. This driver could do something trivial, like monitor several GPIOs, etc.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;modify-and-install-u-boot&quot;&gt;Modify and install U-boot&lt;&#x2F;h4&gt;
&lt;p&gt;U-boot is a common bootloader for Embedded Linux systems (but not the only one). Locate the source code for your embedded board and learn how to build, modify, and install a custom version of U-boot.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;explore-the-many-application-programming-options&quot;&gt;Explore the many Application Programming Options&lt;&#x2F;h4&gt;
&lt;p&gt;There are so many interesting application programming options with Linux. Of course you can stick with traditional C&#x2F;C++. But today, there are many other languages and environments that may be better for various applications (Python, NodeJS, Golang, Qt&#x2F;QML, etc).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;find-something-that-is-broken-and-fix-it&quot;&gt;Find something that is broken and fix it&lt;&#x2F;h4&gt;
&lt;p&gt;There are many opportunities to improve open source code. Find something that does not work quite right, fix it, and get the changes accepted in the upstream project. This will provide valuable experience working with OSS communities. When working with complex systems like Linux, you will run into problems that are very hard to solve. Being comfortable with asking, and getting help from various OSS communities will be key to your success. Again, your mindset is key here. People who don’t have the right mindset will create fake names and email aliases to hide their true identity when asking questions. People with the right mindset are willing to be up front and admit there is something they don’t know.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;helping-others&quot;&gt;Helping Others&lt;&#x2F;h4&gt;
&lt;p&gt;One of the best ways to really learn something is to teach it or help others. Once you reach a certain level of proficiency, there are many opportunities in open source communities (stack overflow, mail lists, IRC, etc) to help others. In doing so, we usually receive back much more than we give.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;maintain-yocto-or-buildroot-support-for-an-embedded-board&quot;&gt;Maintain Yocto or Buildroot support for an embedded board&lt;&#x2F;h4&gt;
&lt;p&gt;There are many embedded Linux platforms out there that are not actively maintained or tested in Yocto or Buildroot. Get involved and help keep the platform current and working in the build system.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;set-up-a-server-in-the-cloud&quot;&gt;Set up a server in the cloud&lt;&#x2F;h4&gt;
&lt;p&gt;It is very cheap (less than $10&#x2F;mo) to set up a server in Amazon AWS, Digital Ocean, Linode, Vultr, or one of the many other cloud providers. Although this is technically not embedded Linux, the skills required are very similar. It will also open up interesting possibilities of creating systems that are a combination of Embedded Linux devices and cloud servers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;publish-an-open-source-project-on-github&quot;&gt;Publish an Open Source project on Github&lt;&#x2F;h4&gt;
&lt;p&gt;Publishing an open source project is a good experience as it helps you learn to create something that is generally useful. For example, I wrote a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;linux-serial-test&quot;&gt;little app&lt;&#x2F;a&gt; to test serial ports and published it on Github. Over the past few years, other people have provided nice contributions to the application, making it much more useful, with little effort on my part. However, I had to spend a little more time up front making the app generally useful and documenting how to use it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Embedded Linux brings a level of functionality to systems that is unmatched by anything else out there, thus its popularity. With this broad scope of functionality comes complexity. Linux has a learning curve, and using it successfully requires some amount of discipline and interaction with various OSS communities. The resources are endless – time and motivation are the only limitations. In life, the rewards are proportional to the effort put forth. If you are committed, working with Embedded Linux is very rewarding, and brings a new level of functionality to products.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git, Versioning, and Branching for Embedded Linux Development</title>
        <published>2018-02-14T00:00:00+00:00</published>
        <updated>2018-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1412/git-versioning-and-branching-for-embedded-linux-development/"/>
        <id>https://bec-systems.com/1412/git-versioning-and-branching-for-embedded-linux-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1412/git-versioning-and-branching-for-embedded-linux-development/">&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2018&#x2F;02&#x2F;versions-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When building a product using Linux, versioning and branching of your software is an important consideration. Everyone’s needs are different depending on the size of the team, culture, and testing requirements, so there is no one size that fits all. However, after working on a number of different projects for a dozen or so different companies, there are several practices that are often used.&lt;&#x2F;p&gt;
&lt;p&gt;The most fundamental is to use Git to manage your software development. It is surprising the number of small companies developing software who do not use Git, or any version control system yet. The many &lt;a href=&quot;&#x2F;723&#x2F;why-git&#x2F;&quot;&gt;benefits of Git stand alone&lt;&#x2F;a&gt;, but the minute you enter into the Linux world (or the Open Source Software (OSS) world in general), there are thousands of projects available, and 99.9% of them are developed in Git. Having a good understanding of Git is essential in using OSS. This is not really specific to Linux development, but rather any modern software development (cloud, web, mobile, etc). Most foundational software technologies today are open source. There is no other development methodology that scales to the complexity of modern software systems, and no one company contains the resources needed to create and maintain these systems. Git does have a steep learning curve and usually requires 2-3 weeks of committed use for new users to become comfortable with it. However, it is well worth it.&lt;&#x2F;p&gt;
&lt;p&gt;An extension of using Git is to consider hosting your Git repositories in the cloud. There are many companies who provide this service at a reasonable cost (some like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.gitlab.com&#x2F;&quot;&gt;Gitlab&lt;&#x2F;a&gt; are free), or it is relatively simple to host your own git server (can be done for $2.50&#x2F;mo at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.vultr.com&#x2F;&quot;&gt;Vultr&lt;&#x2F;a&gt; using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitea.io&quot;&gt;Gitea&lt;&#x2F;a&gt;). Some may balk at putting a company’s valuable IP (intellectual property) assets in the cloud (where hackers might have an easier time getting to them) vs behind the secure company firewall. However, which of the following is the main impediment to your business?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The danger of competitors hacking into your cloud server, stealing your IP, and then implementing a product with it.&lt;&#x2F;li&gt;
&lt;li&gt;Shipping products in a timely fashion, and then maintaining them.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In my observation, #2 seems to be the challenge for most – especially as systems become more complex. Unless you are a top secret government agency, or a cutting edge chip&#x2F;algorithm company, your software IP is probably of marginal use to anyone else. The reason for this is that integration and execution is most often the challenge, not coding. There is plenty of free&#x2F;OSS software out there to do about anything. Integrating this into something that will make a product is the hard part.  It is difficult getting software and hardware to work together, debugging problems, communicating with cloud infrastructure, software updates, maintaining a product, adding features, etc. Modern products are typically not static entities where you design it, toss it over the wall to production, produce millions, make lots of money, and never see it again. Rather modern products are complex, dynamic beasts that have continually changing requirements, bugs to fix, features needed for new customers, manufacturing issues to solve, obsolete parts to replace, and are part of a larger complex system. Execution is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sethgodin.typepad.com&#x2F;seths_blog&#x2F;2007&#x2F;09&#x2F;big-ideas.html&quot;&gt;hard&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;the-mission&#x2F;give-your-ideas-away-f21d8dbf9c1&quot;&gt;valuable&lt;&#x2F;a&gt; part. Increasing developer efficiency and collaboration is important, especially with a distributed team of developers. You can require your developers to use company issued Windows computers and fussy VPNs in an attempt to protect your IP, or you can simply host your Git repositories in the cloud secured by industry proven methods such as https and ssh. As systems become more complex, it is critical to be able to involve domain experts in the project (consultants, contractors, employees at a different office, manufacturing, etc). A Git server in the cloud is the foundation of distributed development collaboration. Emailing zip files may be temping as quick and easy, but it is not a sustainable way to develop products that have so many moving parts. As an extension of this, use a web based Git repository manager (like Gitea, Gitlab, or a hosted solution) to implement your Git server. These repository managers greatly simplify the management of Git repos (teams, users, permissions, creating repositories, issue tracking, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Software should be released with a version number. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;Semantic Versioning&lt;&#x2F;a&gt; is a good place to start. Your needs may vary, but you may as well start with the good ideas of others. Additionally, a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;keepachangelog.com&#x2F;&quot;&gt;changelog&lt;&#x2F;a&gt; should be maintained that lists all changes for each software release. Being able to quickly understand what changed with each release is critical as multiple versions are being used. Keeping a changelog requires a little discipline, but is fairly easy to do if you keep an unreleased section at the top of your changelog file to track changes for the upcoming release, as described in the above link.&lt;&#x2F;p&gt;
&lt;p&gt;A discussion on branching only really makes sense if you are using Git. Source code branches greatly improve your development process flow. The ease with which Git allows you to create and merge source code branches enables development flows which were impractical before Git. With an Embedded Linux project you are typically building images that get loaded on some type of hardware device. In this case, it’s useful to have &lt;em&gt;development&lt;&#x2F;em&gt; and &lt;em&gt;production&lt;&#x2F;em&gt; releases. Production releases are sent to customers, and development releases are used internally to test new features under development. Every software component that is under active development (OE build system, custom applications, kernel, etc) should likewise have production and development branches that feed into their respective builds. For a more extensive discussion of this topic, consider &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;nvie.com&#x2F;posts&#x2F;a-successful-git-branching-model&#x2F;&quot;&gt;this post&lt;&#x2F;a&gt;. Again, start with the good ideas of others, and then use what makes sense. An OE build can be configured to pull from the latest HEAD of your custom components, so that for each new build you get the latest from the respective branches for various components. To do this, you typically have something like the following in a bitbake recipe:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI = &amp;quot;git:&#x2F;&#x2F;git.mycompany.com&#x2F;myproject.git;branch=develop;protocol=ssh;user=git
PV = &amp;quot;4.1.15+git${SRCPV}&amp;quot;
SRCREV = &amp;quot;${AUTOREV}&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In some cases, for production builds we’ll manually specify the Git hash or tag in the bitbake recipe so that versions of all components are explicitly locked down. To specify a git version, replace &lt;em&gt;${AUTOREV}&lt;&#x2F;em&gt; with a Git hash. Either way, if you include the Git version (&lt;em&gt;SRCPV&lt;&#x2F;em&gt;) in the package version (&lt;em&gt;PV&lt;&#x2F;em&gt;) variable, you can always figure out what Git version was used to build a package for a particular release. Below is an example of a package file name:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;my-app_4.1.15+git0+a05d9b23b9-r0.10_var_som_mx6.ipk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, &lt;em&gt;a05d9b23b9&lt;&#x2F;em&gt; tells you what Git version was used to build &lt;em&gt;my-app&lt;&#x2F;em&gt;. This is often adequate if you don’t spend a lot of time building or patching old software releases. With each release of software, it is beneficial to tag the software components used in the build with a version. This allows a clear view of what changed between releases, and allows us to easily check out old versions of software.&lt;&#x2F;p&gt;
&lt;p&gt;With development and production branches, we should consider how to version the different branches. One simple way is to use a sequence like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;1.0.0 (production)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.900 (develop)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.901 (develop)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.1 (production bug fix)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.902 (develop)&lt;&#x2F;li&gt;
&lt;li&gt;merge develop to production and do a new release&lt;&#x2F;li&gt;
&lt;li&gt;1.1.0 (production)&lt;&#x2F;li&gt;
&lt;li&gt;1.1.900 (continue development&lt;&#x2F;li&gt;
&lt;li&gt;1.1.901 (develop)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this case, the development version is always the last production release &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;&lt;em&gt;MAJOR.MINOR&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and the &lt;em&gt;PATCH&lt;&#x2F;em&gt; version starts at 900 and is incremented with each development release. If a version number ends in 9xx, you know it’s a development build. You can use more complex version schemes like 1.1.0-alpha1 (instead of 1.0.901), but then you might run into sorting problems where 1.1.0-alpha1 is listed after 1.1.0, even though 1.1.0 is a later release than 1.1.0-alpha1. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;meta-bec&#x2F;blob&#x2F;master&#x2F;recipes&#x2F;updater&#x2F;files&#x2F;imx6ul-var-dart&#x2F;init#L288&quot;&gt;Recent versions&lt;&#x2F;a&gt; of the &lt;a href=&quot;&#x2F;146&#x2F;do-you-need-software-update&#x2F;&quot;&gt;BEC software updater&lt;&#x2F;a&gt; look at all update files on a USB disk and pick the latest one using a natural sort of version numbers within the text. In the example below, you can see how versions are sorted:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[cbrake@mars ver]$ ls -lv
total 0
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.0
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.1
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.900
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.901
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.1.0
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.1.0-alpha1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, 1.0.9xx works much better for development builds if you want update systems to automatically pick the latest release from a list of options. You can also use versions like 1.0.0+1.1.0-alpha1 to get around the sorting problem if you want something a little more explicit.&lt;&#x2F;p&gt;
&lt;p&gt;Versioning and branching does not have to be complex, and in many cases the above is adequate for small teams. Your needs may vary, but the important thing is to have a source control, versioning, and branching process in place. These practices require some discipline to implement, and may seem unnecessary to those who have not used them, but with a little experience we soon realize that efforts to introduce appropriate amounts of organization and process into our development efforts clearly communicates what we did, what we are doing, and what gets released to production. This then frees us up to focus on what really adds value.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Separation of Source and Build Directories</title>
        <published>2017-11-16T00:00:00+00:00</published>
        <updated>2017-11-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1113/separation-of-build-and-source-directories/"/>
        <id>https://bec-systems.com/1113/separation-of-build-and-source-directories/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1113/separation-of-build-and-source-directories/">&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2017&#x2F;11&#x2F;oe-tree2-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As we work with larger and more complex systems (i.e. Linux), more and more of our time is spent on integration and pulling different pieces together.  We often need to debug or understand code we did not write – especially in build systems.  To work effectively in this scenario you must be able to quickly search through a lot of source code.  Therefore, we are always looking for ways to make this more efficient.&lt;&#x2F;p&gt;
&lt;p&gt;One pattern that is very useful is separating source and build files into two separate directories at the top level of the project.  There are several reasons for this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It is easy to grep the source (or today we &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BurntSushi&#x2F;ripgrep&quot;&gt;ripgrep&lt;&#x2F;a&gt;) if it is not littered with transient build data.&lt;&#x2F;li&gt;
&lt;li&gt;Its easy to reset the build by simply deleting the build directory.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is especially important for large builds like OpenEmbedded, where a build directory can be on the order of 40GiB. If your grep tool has to process 40GiB of data every time it runs, it will be very slow.&lt;&#x2F;p&gt;
&lt;p&gt;This separation should occur at the top level of the project.  Ideally you want something like this for an OpenEmbedded build:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;├── build&#x2F;
│   ├── sstate-cache&#x2F;
│   └── tmp&#x2F;
├── downloads&#x2F;
├── sources&#x2F;
│   ├── bitbake&#x2F;
│   ├── meta-bec&#x2F;
│   ├── meta-browser&#x2F;
│   ├── meta-freescale&#x2F;
│   ├── meta-freescale-3rdparty&#x2F;
│   ├── meta-freescale-distro&#x2F;
│   ├── meta-openembedded&#x2F;
│   ├── meta-qt5&#x2F;
│   ├── meta-variscite-fslc&#x2F;
│   ├── meta-myproject&#x2F;
│   ├── meta-mycompany&#x2F;
│   └── openembedded-core&#x2F;
├── conf&#x2F;
└── etc ...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;sources&lt;&#x2F;em&gt; directory contains OpenEmbedded metadata (core, 3rd party, and your own custom meta-myproject layers).  The &lt;em&gt;downloads&lt;&#x2F;em&gt; directory might contain 3rd party sources or tar balls that are downloaded by the build tool.  And the &lt;em&gt;build&lt;&#x2F;em&gt; directory contains transient build data that can be deleted and re-created at any time.  This configuration is used in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&quot;&gt;Yoe distribution&lt;&#x2F;a&gt;.  It should be noted that in this example, the desire is to cleanly separate OE metadata (source) from build data.  Source code for individual packages is considered build data from an OE perspective.  Most of the development work in this case is creating&#x2F;customizing OE recipes, images, etc, thus the need is to quickly grep the various OE meta layers.&lt;&#x2F;p&gt;
&lt;p&gt;This idea can be contrasted with the Poky reference distribution directory layout:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;├── bitbake 
├── build 
│   ├── cache 
│   ├── conf 
│   ├── downloads 
│   ├── sstate-cache 
│   └── tmp 
├── documentation 
├── meta 
├── meta-poky 
├── meta-selftest 
├── meta-skeleton 
├── meta-yocto-bsp 
└── scripts
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, there are multiple meta directories in the top level.  If you want to search all of the OE meta data, you need to instruct your search tool to exclude the &lt;em&gt;build&lt;&#x2F;em&gt; directory.  Additionally, the build directory is dynamically generated, which includes the conf directory.  If you want to completely reset your build, you need to clean several directories in the build directory.  For a production build, you need some of the conf files to be in revision control; therefore, they are more difficult to manage when they are dynamically generated, or copied from another location.  Why not move conf to the top and use it there?&lt;&#x2F;p&gt;
&lt;p&gt;Most decisions are tradeoffs, so there may be good reasons for the Poky directory structure.  For a reference (demo) distro, simplicity and ease of setup may be valued over reproducibility.  For production builds (builds used in products), rock solid reproducability is important.  To get that, you need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;all source and configuration is locked down in version control&lt;&#x2F;li&gt;
&lt;li&gt;a build should be a minimal number of steps: checkout source, a very simple setup&#x2F;configuration step, and then a build command.  There should be no complex scripts that copy files around that may be modified later, or manual steps.&lt;&#x2F;li&gt;
&lt;li&gt;the output is ready to program into the target.  There are no manual post processing steps.&lt;&#x2F;li&gt;
&lt;li&gt;keep things as simple as possible.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The separation of source and build can also be used&#x2F;observed with many other build systems.  With CMake, if you have a project directory named &lt;em&gt;myproject&lt;&#x2F;em&gt;, you can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mkdir myproject-build
cd myproject-build
cmake ..&#x2F;myproject
make
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Qt Creator also sets up a separate build directory by default.&lt;&#x2F;p&gt;
&lt;p&gt;With the linux kernel, you can specify a separate build directory with the ‘O’ option:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cd linux
mkdir ..&#x2F;linux-build
make O=..&#x2F;linux-build
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Think about directory structure – it can make a difference.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding the NXP i.MX6UL Pin Mux (Part 2)</title>
        <published>2017-11-06T00:00:00+00:00</published>
        <updated>2017-11-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1377/understanding-the-nxp-i-mx6ul-pin-mux-part-2/"/>
        <id>https://bec-systems.com/1377/understanding-the-nxp-i-mx6ul-pin-mux-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1377/understanding-the-nxp-i-mx6ul-pin-mux-part-2/">&lt;p&gt;In the &lt;a href=&quot;&#x2F;1313&#x2F;understanding-the-nxp-i-mx6ul-pin-mux&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt;, it was noted that bit 30 needs to be set in the i.MX6UL pad config if you want to read the state of a GPIO output. Digging into this a bit more, we find the following text in the &lt;em&gt;Documentation&#x2F;devicetree&#x2F;bindings&#x2F;pinctrl&#x2F;fsl,imx-pinctrl.txt&lt;&#x2F;em&gt; file:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;SION(1 &amp;lt;&amp;lt; 30): Software Input On Field.&lt;&#x2F;em&gt;
&lt;em&gt;Force the selected mux mode input path no matter of MUX_MODE functionality. By default the input path is determined by functionality of the selected mux mode (regular).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the i.MX6UL developers manual, we also find the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2017&#x2F;10&#x2F;imx6ul-sion-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When we look at the &lt;em&gt;SW_MUX_CTL&lt;&#x2F;em&gt; register, we notice the &lt;em&gt;SION&lt;&#x2F;em&gt; bit is located at the bit 4 position.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;mux-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the question is: How does bit 30 in the device tree file get mapped to bit 4 in the &lt;em&gt;SW_MUX_CTL&lt;&#x2F;em&gt; register? In the Linux kernel source we find the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;drivers&#x2F;pinctrl&#x2F;freescale&#x2F;pinctrl-imx.c:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;* The bits in CONFIG cell defined in binding doc*&#x2F;
#define IMX_NO_PAD_CTL 0x80000000 &#x2F;* no pin config need *&#x2F;
#define IMX_PAD_SION 0x40000000 &#x2F;* set SION *&#x2F;

...

 &#x2F;* SION bit is in mux register *&#x2F;
 config = be32_to_cpu(*list++);
 if (config &amp;amp; IMX_PAD_SION)
 pin-&amp;gt;mux_mode |= IOMUXC_CONFIG_SION;
 pin-&amp;gt;config = config &amp;amp; ~IMX_PAD_SION;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;drivers&#x2F;pinctrl&#x2F;freescale&#x2F;pinctrl-imx.h&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#define IOMUXC_CONFIG_SION (0x1 &amp;lt;&amp;lt; 4)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From this code, we can see that bit 30 is a virtual bit that gets translated into bit 4 in the mux mode register.&lt;&#x2F;p&gt;
&lt;p&gt;Hope this helps in understanding how to configure the i.MX6UL gpio. Once you understand the details; the process is very simple.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding the NXP i.MX6UL Pin Mux</title>
        <published>2017-09-14T00:00:00+00:00</published>
        <updated>2017-09-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1313/understanding-the-nxp-i-mx6ul-pin-mux/"/>
        <id>https://bec-systems.com/1313/understanding-the-nxp-i-mx6ul-pin-mux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1313/understanding-the-nxp-i-mx6ul-pin-mux/">&lt;p&gt;&lt;em&gt;(note, the article is also applicable to the i.MX6ULL as these processors are very similar)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The NXP i.MX6UL application processor has a very flexible pin multiplexer, that is somewhat difficult to understand at first glance.  Most times when we’re configuring the pin mux in Linux, we modify Device Tree files, so perhaps that is the place to start.  The pin mux options for the i.MX6UL are defined in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git&#x2F;tree&#x2F;arch&#x2F;arm&#x2F;boot&#x2F;dts&#x2F;imx6ul-pinfunc.h?h=v4.11#n155&quot;&gt;&lt;em&gt;arch&#x2F;arm&#x2F;boot&#x2F;dts&#x2F;imx6ul-pinfunc.h&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; file.  The arguments to the macros in this file are defined as:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;*
 * The pin function ID is a tuple of
 * &amp;lt;mux_reg conf_reg input_reg mux_mode input_val&amp;gt;
 *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first 5 are defined in the pinfunc.h file, where the config value is defined in a user’s DTS file.  As an example, consider the following section from &lt;em&gt;imx6ul-pinfunc.h.&lt;&#x2F;em&gt; Column headings are added for clarity.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;&#x2F; headings:                                  mux_  conf_   input_ mux_ input
&#x2F;&#x2F;                                            reg   reg     reg    val  _val
#define	MX6UL_PAD_GPIO1_IO09__PWM2_OUT        0x0080 0x030C 0x0000 0    0
#define	MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY  0x0080 0x030C 0x0000 1    0
#define	MX6UL_PAD_GPIO1_IO09__SPDIF_IN        0x0080 0x030C 0x0618 2    0
#define	MX6UL_PAD_GPIO1_IO09__CSI_HSYNC       0x0080 0x030C 0x0524 3    1
#define	MX6UL_PAD_GPIO1_IO09__USDHC2_RESET_B  0x0080 0x030C 0x0000 4    0
#define	MX6UL_PAD_GPIO1_IO09__GPIO1_IO09      0x0080 0x030C 0x0000 5    0
#define	MX6UL_PAD_GPIO1_IO09__USDHC1_RESET_B  0x0080 0x030C 0x0000 6    0
#define	MX6UL_PAD_GPIO1_IO09__UART5_DCE_CTS   0x0080 0x030C 0x0000 8    0
#define	MX6UL_PAD_GPIO1_IO09__UART5_DTE_RTS   0x0080 0x030C 0x0640 8    2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the i.MX6UL processor reference manual (IOMUX Controller chapter), we can determine the mux_reg is indeed located at offset 0x80.  We can also see that the &lt;em&gt;mux_val&lt;&#x2F;em&gt; values match MUX_MODE in the datasheet.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;mux-reg-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;mux-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;mux_val&lt;&#x2F;em&gt; in the &lt;em&gt;imx6ul-pinfunc.h&lt;&#x2F;em&gt; file also match the MUX_MODE field values in the above register.&lt;&#x2F;p&gt;
&lt;p&gt;The config register can also be located in the datasheet.  Again, we notice that the offset of 0x30C matches &lt;em&gt;config_reg&lt;&#x2F;em&gt; setting.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;cfg-reg-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;cfg-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lets consider the last option listed in the pinfunc file: UART5_DTE_RTS.  The input register is used to mux a pin to an input function inside the SOC – in this case, the UART5_RTS_B input.  We find the input register at offset 0x640 and can see that the input value of 0x2 matches what we would expect in the reference manual.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;input-reg-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;input-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So, how do we know if the pinmux is configured correctly for a pin?  One way is to use devmem2 and dump the register contents directly from user space:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@imx6ul-var-dart:&#x2F;sys&#x2F;class&#x2F;gpio# devmem2 0x20e0080
&#x2F;dev&#x2F;mem opened.
Memory mapped at address 0x76f02000.
Read at address  0x020E0080 (0x76f02080): 0x00000005
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The mux value is 0x5, which configures the pin for the default GPIO1_9 function.  Next we can look at the config register:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@imx6ul-var-dart:&#x2F;sys&#x2F;class&#x2F;gpio# devmem2 0x20e030C
&#x2F;dev&#x2F;mem opened.
Memory mapped at address 0x76f0b000.
Read at address  0x020E030C (0x76f0b30c): 0x000010B0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we further decode the bits in this register we find:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Bit index: 12─╮  8─╮  4─╮  0─╮ 
Bits:         1 0000 1011 0000
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and can conclude that the following options are set:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;bits 3-5 = 6: DSE_43ohm&lt;&#x2F;li&gt;
&lt;li&gt;bits 6-7 = 2: Medium speed (100MHz)&lt;&#x2F;li&gt;
&lt;li&gt;bit 12: PKE: Pull&#x2F;Keeper Enabled&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are additional options that can be configured such as hysteresis, pull up&#x2F;down, open drain, and slew rate.  I&#x2F;O is very configurable on this device!&lt;&#x2F;p&gt;
&lt;p&gt;If we want to use this pin as a GPIO, it appears that everything is configured correctly, so let’s give it a try.  GPIO in the i.MX6UL is banked in 32 bit registers, so we need to map this to a sequential GPIO in Linux.  The formula for this mapping is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;linux gpio number = (gpio_bank - 1) * 32 + gpio_bit&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For GPIO1_9, this would be GPIO9.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;linux gpio number = (1 - 1) * 32 + 9 = 9&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To read the GPIO, execute the following commands:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@imx6ul-var-dart:~# cd &#x2F;sys&#x2F;class&#x2F;gpio&#x2F;
root@imx6ul-var-dart:~# echo 9 &amp;gt; export
root@imx6ul-var-dart:~# cat gpio9&#x2F;value
0 (current gpio value)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another nuance of configuring the i.MX6UL pin mux in Linux is that for GPIO outputs, you need to set a magical bit 30 in the Device Tree configuration as show below.  If you don’t set bit 30, it will always read back as 0.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x4001b0b0 &#x2F;* 2_nSLEEP *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The reason for this will be explored in a future post.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why Git?</title>
        <published>2016-08-18T00:00:00+00:00</published>
        <updated>2016-08-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/723/why-git/"/>
        <id>https://bec-systems.com/723/why-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/723/why-git/">&lt;p&gt;Some time back, I gave a &lt;a href=&quot;&#x2F;video&#x2F;2010-08-26_git.ogv&quot;&gt;presentation&lt;&#x2F;a&gt; that included an overview of the Git version control system.  I still occasionally get asked why Git should be used instead of Subversion, as it seems harder at first.  Most developers don’t really understand Git until they have used it for awhile, and then they will have an “aha moment.”  There are 3 features of Git that are especially interesting to me:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;many repositories (vs. one large repository)&lt;&#x2F;li&gt;
&lt;li&gt;distributed development&lt;&#x2F;li&gt;
&lt;li&gt;cheap branches&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The fundamental driver for better tools is increasing system complexity.  Developers are required to manage and integrate more third party software, work in distributed teams, and more effectively re-use the software we do have.  Git is a tool that helps you accomplish these goals.&lt;&#x2F;p&gt;
&lt;p&gt;Git is a fairly new project, but it is already nearly universal among open source software projects.  Its uptake and acceptance speaks for itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;many-repositories&quot;&gt;Many Repositories&lt;&#x2F;h2&gt;
&lt;p&gt;In the past when most companies used Subversion, there was one huge company repository (I’ve seen them in the 10’s of GB in size) that held a hierarchical tree of all the company source code.  This worked fairly well, and is comfortable in that it is very similar to a file system directory structure.  However, this model is not very flexible in that it does not have a consistent way to re-use components between different projects.  Some people simple copy source code.  Some have a “common” project that is included in all their other projects.  Subversion externals can be used.  But with Git, typically a separate repository is created for each software component.  There are perhaps several reasons for this, but one reason is that Git simply does not scale to huge multi-GByte repositories.  However, this turns out to be a blessing in disguise as I think it is a better model in many cases.  What we end up with is more of a catalog of software components rather than a rigid hierarchy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;svn-vs-git_600-1.png&quot; alt=&quot;svn-vs-git_600&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There is much emphasis these days made on modular, re-usable software components (Object Oriented Programming, plugins, etc.).  Why not keep things modular at the repository level?  Another example of this type of organization is the Internet itself.  It is not a hierarchy of information, but rather a flat system that is organized by hyperlinks.&lt;&#x2F;p&gt;
&lt;p&gt;One of the benefits of organizing your source code this way is that it encourages clean boundaries between software components.  Each software component needs to stand on its own fairly well without being propped up by header files located in an unrelated source tree 3 levels up in the directory hierarchy.  This type of organization forces us to make better use of standard build system practices.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distributed-development&quot;&gt;Distributed Development&lt;&#x2F;h2&gt;
&lt;p&gt;The “many repository” paradigm has been partly driven by the distributed development paradigm.  Git solves the problem of multiple developers working in multiple repositories very well.  Because we want to use and customize projects like the Linux kernel, U-boot, and OpenEmbedded in our projects, then we naturally find ourself in the situation where we need to manage multiple repositories.  Yes, you can check the Linux kernel into your company Subversion repository, but you are much better off long term if you bite the bullet and implement your own Git infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;As we consider the product development process, we need to consider the life cycle of a product.  Most products live for at least several years, and will go through several software iterations.  If we can update the software components we use, then we can add value to the product in the form of new or updated drivers to support new peripherals, new libraries, performance improvements, etc.  But we are dealing with millions of lines of source code, so we must have an efficient way to deal with software projects of this size.  The below Figure 2, below, illustrates how you might organize a typical project.  Notice we can pull updates from the U-boot and Kernel source trees at any time in the development process.  We might have an outside team working an application, and we then easily synchronize the repositories when it makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;git-distributed_600-1.png&quot; alt=&quot;git-distributed_600&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many other design flows possible.  Once you have the ability to support multiple branches and repositories easily, it becomes trivial to implement a staging&#x2F;testing repository for QA processes, maintenance repositories for supporting old releases, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cheap-branches&quot;&gt;Cheap Branches&lt;&#x2F;h2&gt;
&lt;p&gt;The last feature discussed in this article is that of cheap branches.  Just as Git excels in allowing us easily integrate changes from multiple repositories at a team level, Git also allows us to easily work with multiple branches at the personal developer level.  This is a revolutionary feature, and perhaps has to be experienced to be fully appreciated.  With SVN, branching and merging is painful; therefore branches are not used a lot.  In Git, branches are easy, therefore branching is naturally encouraged.  Below is a typical flow of development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;cheap-branches-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;cheap-branches-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In this case, a developer is working on a performance improvement that is largely experimental – depending how it works out, it may or may not be used.  So he starts a branch and experiments with various changes.  As he goes along, he makes nice granular commits that are easy to follow.  He may reach a dead-end, delete the branch and start a new one.  In this middle of this development, his boss asks him to make a quick bug fix.  He checks out master, makes the change, switches back to the branch and keeps working.  The switching between branches takes seconds and is very easy.  Finally, he has some performance changes he is happy with.  He merges master to his perf-improvement branch and tests his changes with the latest master changes.  Everything looks good, so he then merges his branch to master.  Git makes this type of development flow natural and easy.  Because branching is painful in SVN, changes tend to be made in large commits that are difficult to understand.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to keep separate tasks isolated is analogous to having a clean, neat desk with only one thing on it, or having a messy desk with a half a dozen different projects going at once.  Git is a tool to help maintain different working contexts, and it allows work to be staged in a natural flow.  In the end, Git will change how you work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Go in place of a Spreadsheet</title>
        <published>2016-06-28T00:00:00+00:00</published>
        <updated>2016-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1303/using-go-in-place-of-a-spreadsheet/"/>
        <id>https://bec-systems.com/1303/using-go-in-place-of-a-spreadsheet/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1303/using-go-in-place-of-a-spreadsheet/">&lt;p&gt;Recently I needed to calculate NAND partition tables for a project where we will be supporting a number of different flash parts from 500MB to 2GB.  I first tried this in a spreadsheet, but found it difficult to work easily with hex numbers and do the calculations I needed.  I then looked into options for formatting text in columns from a program and found the nice &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;pkg&#x2F;text&#x2F;tabwriter&#x2F;&quot;&gt;text&#x2F;tabwriter&lt;&#x2F;a&gt; Go library.  With a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;go-partition-calcs&quot;&gt;few lines of code&lt;&#x2F;a&gt;, I was then able to get the below output, which is quite easy to read.  The only tricky part was figuring out that for right justified data, you need to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;not use tabs for the padding character&lt;&#x2F;li&gt;
&lt;li&gt;add a trailing \t in the input data&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The Go stdlib is quite extensive, and often has everything you need.  This makes “go run” a nice solution for scripting tasks.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Old Partitions
  Device       Name       Start     Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0     0x80000        0.5           4
    mtd1      uboot     0x80000    0x1c0000       1.75          14
    mtd2  uboot env    0x240000     0x40000       0.25           2
    mtd3      linux    0x280000    0xa00000         10          80
    mtd4     rootfs    0xc80000  0x186a0000    390.625        3125
    mtd5       data  0x19320000  0x26ce0000    620.875        4967
total size = 0x40000000, 1024MiB

New Partitions 500MB
  Device       Name       Start    Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0    0x80000        0.5           4
    mtd1      uboot     0x80000   0x500000          5          40
    mtd2  uboot env    0x580000    0x40000       0.25           2
    mtd3     linux1    0x5c0000  0x1400000         20         160
    mtd4     linux2   0x19c0000  0x1400000         20         160
    mtd5    rootfs1   0x2dc0000  0xa000000        160        1280
    mtd6    rootfs2   0xcdc0000  0xa000000        160        1280
    mtd7        log  0x16dc0000   0xa00000         10          80
    mtd8       data  0x177c0000  0x7c40000     124.25         994
total size = 0x1f400000, 500MiB

size of boot partitions:  45.75 MiB

New Partitions 1G
  Device       Name       Start     Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0     0x80000        0.5           4
    mtd1      uboot     0x80000    0x500000          5          40
    mtd2  uboot env    0x580000     0x40000       0.25           2
    mtd3     linux1    0x5c0000   0x1400000         20         160
    mtd4     linux2   0x19c0000   0x1400000         20         160
    mtd5    rootfs1   0x2dc0000   0xfa00000        250        2000
    mtd6    rootfs2  0x127c0000   0xfa00000        250        2000
    mtd7        log  0x221c0000   0x3200000         50         400
    mtd8       data  0x253c0000  0x1ac40000     428.25        3426
total size = 0x40000000, 1024MiB

size of boot partitions:  45.75 MiB

New Partitions 2G
  Device       Name       Start     Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0     0x80000        0.5           4
    mtd1      uboot     0x80000    0x500000          5          40
    mtd2  uboot env    0x580000     0x40000       0.25           2
    mtd3     linux1    0x5c0000   0x1400000         20         160
    mtd4     linux2   0x19c0000   0x1400000         20         160
    mtd5    rootfs1   0x2dc0000  0x1f400000        500        4000
    mtd6    rootfs2  0x221c0000  0x1f400000        500        4000
    mtd7        log  0x415c0000   0x6400000        100         800
    mtd8       data  0x479c0000  0x38640000     902.25        7218
total size = 0x80000000, 2048MiB

size of boot partitions:  45.75 MiB
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt; &lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Docker for OE&#x2F;Yocto builds</title>
        <published>2016-04-21T00:00:00+00:00</published>
        <updated>2016-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1281/using-docker-for-oeyocto-builds/"/>
        <id>https://bec-systems.com/1281/using-docker-for-oeyocto-builds/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1281/using-docker-for-oeyocto-builds/">&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;04&#x2F;docker_small_h-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;04&#x2F;docker_small_h-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Why Docker?  When using OE to build software for products, we often run into the scenario where software needs to be built using the same version of OpenEmbedded over the course of several years.  Production builds need to be predictable.  We’ve also observed that old versions of OE often break as new Linux distros come out.  This is just the result of the complexity of building tool chains.  Additionally, for predictable builds you really don’t want to be changing the build OS.  This requirement automatically rules out Arch Linux, Debian Unstable, Gentoo, etc as production build machines.  Additionally, having developers debug OE build issues on varying workstation distributions is frustrating and time consuming.&lt;&#x2F;p&gt;
&lt;p&gt;There are several options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;keep a golden build machine around with a fixed OS&lt;&#x2F;li&gt;
&lt;li&gt;do builds in cloud on a machine with a fixed OS&lt;&#x2F;li&gt;
&lt;li&gt;build in a systemd-nspawn, or chroot&lt;&#x2F;li&gt;
&lt;li&gt;build in a virtual machine (Virtualbox, etc)&lt;&#x2F;li&gt;
&lt;li&gt;use Docker&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I have used all of the above and recently started experimenting with Docker.  As an example, I set up a container named &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;cbrake&#x2F;oe-build&#x2F;&quot;&gt;cbrake&#x2F;oe-build&lt;&#x2F;a&gt; and provided an example of how to use a Debian based container for OE builds.&lt;&#x2F;p&gt;
&lt;p&gt;Docker requires a bit of a mind-shift from virtual machines.  The 1st aha moment with Docker comes when you realize data and build directories should be mapped from the host into the container such that the container does not really have any state.  There are no ssh keys, etc in the container.  This allows the container to be immutable and easily replicated across any number of machines.  Stuff that needs to change goes in your build directory and is managed using Git.  Users specific information lives on your host machine.&lt;&#x2F;p&gt;
&lt;p&gt;The 2nd aha moment with Docker is running commands with Docker instead of working in the context of Docker.  For years, I have run OE builds in a systemd-nspawn.  I’d always have two terminal windows open – one for the container context, and one for the host.  With Docker, you typically just work in your host context, and spin up a Docker container every time you need to run a command in the container (bitbake, etc).  If you define a few shell functions to wrap the docker commands, you hardly even know that commands are executing in the container.  This might seem impractical, but it actually works quite well.  Of course you can still run a container shell and work in the context of the container if you want, but its not really necessary or desired once you get the container set up.&lt;&#x2F;p&gt;
&lt;p&gt;Docker is a neat tool and allows you to have a consistent environment for developer and production build machines.  It also encourages a natural separation of immutable containers and transient data that makes it much simpler to manage and distribute containers.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up a Go development environment</title>
        <published>2016-04-15T00:00:00+00:00</published>
        <updated>2016-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1275/setting-up-a-go-development-environment/"/>
        <id>https://bec-systems.com/1275/setting-up-a-go-development-environment/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1275/setting-up-a-go-development-environment/">&lt;p&gt;Go has a pretty neat development environment, and its helpful to set up a standard GOPATH on your workstation up front.  This is what I do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;mkdir ~&#x2F;go&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;add the following to .bashrc (or some file that configures your env on login)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;export GOPATH=~&#x2F;go&lt;&#x2F;li&gt;
&lt;li&gt;export PATH=$GOPATH&#x2F;bin:$PATH&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now, after you log in, you can do things like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;go get -u github.com&#x2F;monochromegane&#x2F;the_platinum_searcher&#x2F;...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;go get -u github.com&#x2F;schachmat&#x2F;wego
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;(set up wego with forcast developer key)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;godoc.org&#x2F;&quot;&gt;lots of&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gowalker.org&#x2F;&quot;&gt;Go apps&lt;&#x2F;a&gt; out there and if you just set up a global GOPATH, they are trivial to install and use anywhere on your system!  Generally your ~&#x2F;go directory is also used for Go development projects, but that is a topic for another day.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go Language for Embedded ARM Linux Systems</title>
        <published>2016-03-08T00:00:00+00:00</published>
        <updated>2016-03-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1269/go-language-for-embedded-arm-linux-systems/"/>
        <id>https://bec-systems.com/1269/go-language-for-embedded-arm-linux-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1269/go-language-for-embedded-arm-linux-systems/">&lt;p&gt;In the quest for technologies that work well for embedded Linux systems, I recently gave Go another try.  The &lt;a href=&quot;&#x2F;579&#x2F;the-go-language-for-embedded-systems&#x2F;&quot;&gt;last time&lt;&#x2F;a&gt;I tried this was very early on and there were some floating point issues on ARM that appear to be fixed now.  Having spent a few days porting an existing application to Go, there is a lot to like about Go.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Compiles very fast&lt;&#x2F;li&gt;
&lt;li&gt;Nice set of default libraries that are nice to use&lt;&#x2F;li&gt;
&lt;li&gt;Binaries are reasonable size&lt;&#x2F;li&gt;
&lt;li&gt;Memory usage is reasonable&lt;&#x2F;li&gt;
&lt;li&gt;Very simple to deploy (run time and libs are bundled with a single executable)&lt;&#x2F;li&gt;
&lt;li&gt;many 3rd party libraries available&lt;&#x2F;li&gt;
&lt;li&gt;Tooling is good (build, unit testing, etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As an example of running a Go app on an embedded Linux system, enter the following in hello.go:&lt;&#x2F;p&gt;
&lt;p&gt;package main&lt;&#x2F;p&gt;
&lt;p&gt;import (&lt;&#x2F;p&gt;
&lt;p&gt;“fmt”&lt;&#x2F;p&gt;
&lt;p&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;func main() {&lt;&#x2F;p&gt;
&lt;p&gt;fmt.Println(“Hello”);&lt;&#x2F;p&gt;
&lt;p&gt;}&lt;&#x2F;p&gt;
&lt;p&gt;To run on x86:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;go run Hello.go
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To build for ARM Linux:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ GOARCH=arm GOARM=5 go build hello.go
$ file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, cross compiling is very easy with Go.&lt;&#x2F;p&gt;
&lt;p&gt;Now, to try this exe on a Raspberry PI 3 running Arch Linux:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[root@alarmpi ~]# .&#x2F;hello
Hello
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I did notice the time to build for ARM is a bit longer than building for x86:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ time go build hello.go

real	0m0.262s
user	0m0.337s
sys	0m0.030s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;$ time GOARCH=arm GOARM=5 go build hello.go
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;real	0m2.533s
user	0m4.930s
sys	0m0.183s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But, still pretty reasonable considering what all it is doing.  The simplicity of all this is very attractive.  There is no runtime to cross compile and deploy.  Just one executable and you’re good to Go.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IOT Protocols: MQTT vs CoAP vs HTTP</title>
        <published>2015-12-11T00:00:00+00:00</published>
        <updated>2015-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1200/iot-protocols-mqtt-vs-coap-vs-http/"/>
        <id>https://bec-systems.com/1200/iot-protocols-mqtt-vs-coap-vs-http/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1200/iot-protocols-mqtt-vs-coap-vs-http/">&lt;p&gt;With the explosion of IOT (Internet of things), there are now more technologies we can use to build systems.  In reality, we’ve been doing IOT for years.  We’ve been networking devices for a long time.  We’ve been collecting data from remote nodes.  This is nothing new, but what the IOT movement brings to the table is technologies that are much lower cost, and more standardized.  Two of these technologies are MQTT and CoAP.  Both very interesting, and very useful.  Recently, I helped a system manufacturer think through the architecture of a system with the following requirements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;They plan to sell a relatively small number (200-1000) of fairly expensive machines ($5,000-$10,000).  The point here is we are not dealing with millions of $10 nodes, which is really the vision of IOT.&lt;&#x2F;li&gt;
&lt;li&gt;There might be as many as a dozen machines installed in each location.&lt;&#x2F;li&gt;
&lt;li&gt;Users of these machines need to monitor them remotely.  The manufacturer would also like to monitor them for diagnostics and customer support.&lt;&#x2F;li&gt;
&lt;li&gt;The machines can be connected to the Internet at the install sites.&lt;&#x2F;li&gt;
&lt;li&gt;These machines are installed at various locations where the manufacturer doesn’t have much control over the network (firewall, filtering, which ports are blocked, etc).&lt;&#x2F;li&gt;
&lt;li&gt;The machines don’t need to talk to each other.&lt;&#x2F;li&gt;
&lt;li&gt;It should be relatively difficult to hack into a machine and mess up what it is doing.&lt;&#x2F;li&gt;
&lt;li&gt;Data will be mostly going from machines to the cloud.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There are several ways to address these requirements, but one of the simplest today is for each machine to talk to a server in the cloud, and then users monitor and control the machines through a web application running in the cloud.  The web application can be designed to be viewed on both personal computers and mobile devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;12&#x2F;IOT-protocols-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;12&#x2F;IOT-protocols-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the question is which protocol do we use to communicate from the installed machines to the cloud?  In this case, we really do not need a lot of efficiency, as the number of nodes is relatively small.  Bandwidth requirements are not really a huge concern because a) the number of nodes is relatively small, and b) we can use the existing broadband infrastructure at the install sites.  While it might be interesting to use one of the new protocols like MQTT or CoAP, we need to carefully consider them in the context of requirement #5 – we don’t have control over what ports are blocked or what type of filtering&#x2F;proxying happens at the install site.  Support costs can run very high debugging networking problems at remote locations.  Because MQTT and CoAP typically use non-standard ports, they are less attractive for this application.  Even if we did run MQTT or CoAP over port 80, the install site might have internet filters or proxies that would reject non HTTP data.  So this puts us back to HTTP, perhaps with a REST implementation.  As it turns out, this is not a bad way to go.  Even though HTTP is old, it is still a perfectly valid protocol for this application.  Some of the advantages include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP is the most compatible with existing network infrastructure, and you are pretty much guaranteed HTTP will work.  If a web browser works, then machines in this scenario should be able to send data to the cloud.&lt;&#x2F;li&gt;
&lt;li&gt;Stateless HTTP&#x2F;REST will traverse firewalls and NAT systems easily.  Again, web browsers work.&lt;&#x2F;li&gt;
&lt;li&gt;Because the Machines initiate the connection to the server (users are not connecting directly to a browser on the machine), the machines are much easier to secure.  Thy don’t even need any open ports.  Most of the security effort in this system only needs to be focused in one place (cloud server).&lt;&#x2F;li&gt;
&lt;li&gt;HTTP provides well understood authentication and encryption mechanisms.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are other applications where MQTT or CoAP might make more sense.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In a system connected via cellular modems where data is very expensive, you might want to consider CoAP, because it can use UDP which eliminates the overhead of TCP&#x2F;IP, which is significant (both MQTT and HTTP require TCP&#x2F;IP).  Especially if you have 1000’s of nodes, and are trying to keep the monthly usage of each one under 5MB.&lt;&#x2F;li&gt;
&lt;li&gt;If the various machines need to talk to each other, then MQTT would be a good choice.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While I’d like to use MQTT or CoAP, in this application I’m going to recommend they stick with HTTP(S).  Even though MQTT might be more convenient to work with, the support costs of debugging network issues at install sites will probably swamp any advantages during development.  This project can benefit from the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.esp8266.com&#x2F;&quot;&gt;host of&lt;&#x2F;a&gt; Wifi &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.arduino.cc&#x2F;en&#x2F;Main&#x2F;ArduinoMKR1000&quot;&gt;enabled&lt;&#x2F;a&gt; microcontroller &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.particle.io&#x2F;&quot;&gt;systems&lt;&#x2F;a&gt;, low cost &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxgizmos.com&#x2F;tiny-iot-sbc-runs-openwrt-on-mediatek-mips-soc&#x2F;&quot;&gt;embedded Linux&lt;&#x2F;a&gt; technologies, or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AdisonTech&quot;&gt;cloud technologies&lt;&#x2F;a&gt; aimed at IOT systems.  All of these support HTTP just fine.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded &#x2F; Yocto Usage Survey</title>
        <published>2015-11-18T00:00:00+00:00</published>
        <updated>2015-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1175/openembedded-yocto-usage-survey/"/>
        <id>https://bec-systems.com/1175/openembedded-yocto-usage-survey/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1175/openembedded-yocto-usage-survey/">&lt;p&gt;Recently, I sent a survey to the OpenEmbedded and Yocto mail lists asking a series of questions about how they use OE.  38 people responded.  The average number of years using OE is 4.8 years.&lt;&#x2F;p&gt;
&lt;p&gt;Below are the results of the questions.  (update 2015-11-23 – the below numbers are absolute numbers, not percentage)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart1-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart1-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart2-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart2-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart3-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart3-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart4-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart4-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart5-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart5-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart61-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart61-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart7-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart7-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart8-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart8-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart9-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart9-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart10-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart10-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On the question about tooling, 4 people responded they use Toaster (two specified toaster analysis mode).  Two use devtool.  One uses ADT.&lt;&#x2F;p&gt;
&lt;p&gt;I plan to follow up with additional articles discussing some of these results.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to all who responded to this survey.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rebasing a set of changes with Git</title>
        <published>2015-11-11T00:00:00+00:00</published>
        <updated>2015-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1159/rebasing-a-set-of-changes-with-git/"/>
        <id>https://bec-systems.com/1159/rebasing-a-set-of-changes-with-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1159/rebasing-a-set-of-changes-with-git/">&lt;p&gt;One of the common things we do during Linux kernel development is move a series of patches from one kernel version to a similar version (say Linux 4.1 to 4.1.12).  This is required as new stable versions of particular kernel version are released.  One approach is to merge, but then your changes are mixed in with upstream commits and are more difficult to manage.  Git rebase offers a convenient way to move a set of patches.  In the following example we have a series of changes we made (or patches we applied) on top of the 4.1 kernel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git1-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git1-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now we want to move the same patchset to the 4.1.12 stable kernel.  To do this, we can use the following commands:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;git checkout -b 4.1.12-armv7-x0-dugen2 4.1-armv7-x0-dugen2 (create a new branch that will be rebased)&lt;&#x2F;li&gt;
&lt;li&gt;git rebase --onto v4.1.12 v4.1 4.1.12-armv7-x0-dugen2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A few details on the git rebase arguments:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;--onto v4.1.12  (this tells git what version we want to move our changes to)&lt;&#x2F;li&gt;
&lt;li&gt;v4.1 (upstream – tells git where our patchset starts)&lt;&#x2F;li&gt;
&lt;li&gt;4.1.12-armv7-x0-dugen2 (branch – is the branch to do the operation on)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After the rebase, our patchset looks very similar, only on top of the 4.1.12 kernel version.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git2-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git2-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It this example (which included many more patches than shown above), I only encountered one conflict which was easy to resolve.  This process can also be used to move a patchset to a new kernel version (say 4.2, or 4.3), but you would obviously expect more conflicts.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Modifying the BusyBox config in OpenEmbedded</title>
        <published>2015-09-30T00:00:00+00:00</published>
        <updated>2015-09-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1145/modifying-the-busybox-config-in-openembedded/"/>
        <id>https://bec-systems.com/1145/modifying-the-busybox-config-in-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1145/modifying-the-busybox-config-in-openembedded/">&lt;p&gt;Recently, I needed to enable the &lt;em&gt;eject&lt;&#x2F;em&gt; command in BusyBox for an OpenEmbedded (Yocto) based project.  Below is a way to do this in a fairly painless way:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;bitbake -c menuconfig busybox (enable the eject command in the config and save)&lt;&#x2F;li&gt;
&lt;li&gt;bitbake -c diffconfig busybox (this generates a config fragment, note the fragment file location)&lt;&#x2F;li&gt;
&lt;li&gt;recipetool appendsrcfile -w [path to layer] busybox [path to fragment generated in step #2]&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now, in my project layer, I have the following files:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;recipes-core&#x2F;busybox&#x2F;busybox_%.bbappend:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI += &amp;quot;file:&#x2F;&#x2F;fragment.cfg&amp;quot;
FILESEXTRAPATHS_prepend := &amp;quot;${THISDIR}&#x2F;${PN}:&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;recipes-core&#x2F;busybox&#x2F;busybox&#x2F;fragment.cfg:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# Wed Sep 30 15:23:49 2015
CONFIG_EJECT=y
CONFIG_FEATURE_EJECT_SCSI=y
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wow, that is pretty neat!  The same procedure should work on kernel recipes as well.&lt;&#x2F;p&gt;
&lt;p&gt;Notes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If you have trouble running &lt;em&gt;bitbake -c menuconfig&lt;&#x2F;em&gt; in a remote ssh shell, trying installing screen on the build machine.&lt;&#x2F;li&gt;
&lt;li&gt;recipetool is located in &lt;em&gt;openembedded-core&#x2F;scripts&#x2F;recipetool&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;&quot;&gt;Chris L.&lt;&#x2F;a&gt; noted the -w option in recipetool would have simplified the append slightly (would avoid the subdir= on the SRC_URI, since it’d install it to workdir instead of the source tree)   Great idea – example above modified to include -w.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for using CMake in OpenEmbedded&#x2F;Yocto</title>
        <published>2015-03-10T00:00:00+00:00</published>
        <updated>2015-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1128/best-practices-for-using-cmake-in-openembeddedyocto/"/>
        <id>https://bec-systems.com/1128/best-practices-for-using-cmake-in-openembeddedyocto/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1128/best-practices-for-using-cmake-in-openembeddedyocto/">&lt;p&gt;I’ve already written about using &lt;a href=&quot;&#x2F;509&#x2F;best-practices-for-building-gtk-applications-with-openembedded&#x2F;&quot;&gt;autotools&lt;&#x2F;a&gt; and &lt;a href=&quot;&#x2F;501&#x2F;best-practices-for-building-qt-applications-with-openembedded&#x2F;&quot;&gt;qmake&lt;&#x2F;a&gt; in OE.  With recent projects, we’re using CMake to build most C&#x2F;C++ components.  Like any good tool, CMake has a learning curve, but it seems to do its job quite well.  Below are examples of a CMake build file, and corresponding OE recipe.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;CMakeLists.txt&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cmake_minimum_required(VERSION 2.8)
project(MyApp)
file(GLOB_RECURSE src&#x2F;*.cpp)
add_executable(MyAPP ${src_files})
target_link_libraries(MyApp pthread)
install(TARGETS MyApp DESTINATION bin)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;myapp.bb (OE recipe)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;DESCRIPTION = “My xyz app” LICENSE = “CLOSED” inherit cmake SRCREV = “${AUTOREV}” PV = “1.1+gitr${SRCPV}” SRC_URI = “git:&#x2F;&#x2F;my-git-server&#x2F;myapp.git;branch=master;protocol=ssh;user=git” S = “${WORKDIR}&#x2F;git” BBCLASSEXTEND = “native”&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Notice the OE recipe above has no build&#x2F;install logic other than “inherit cmake”.&lt;&#x2F;p&gt;
&lt;p&gt;Below are some tips on using CMake.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;put your source files in a src directory.  This allows you to easily build a list by using GLOB patterns.  If you put the source files in the root directory of your application source, then the GLOB pattern will also find temporary C files that CMake generates, and you’ll get multiple “main” errors.  Some recommend against using GLOB patterns for finding source files because it may miss additions, but in practice I find the benefits of this pattern outweigh the negatives.&lt;&#x2F;li&gt;
&lt;li&gt;do all install operations in CMake if possible (vs do_install in the OE recipe).  The reason for this is its &lt;strong&gt;much&lt;&#x2F;strong&gt; easier to debug install in CMake then OE.  You can build the app for x86 on your workstation, run “make install” and easily verify the files get installed correctly.  Typically, things get installed in &#x2F;usr&#x2F;local when building on your workstation, and &#x2F;usr when built in the context of OE.&lt;&#x2F;li&gt;
&lt;li&gt;do most of your development on your workstation.  Most of the time, you can test 99% of an application’s functionality on your workstation.  Do what you can there with unit tests where development is much faster and easier.&lt;&#x2F;li&gt;
&lt;li&gt;change ownership of &#x2F;usr&#x2F;local by running “&lt;em&gt;sudo chown -R $USER &lt;a href=&quot;&#x2F;usr&#x2F;local&quot;&gt;&#x2F;usr&#x2F;local&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;”.  This allows you to run “make install” of the CMake project during development without sudo.  It also helps ensure you are not accidentally installing stuff outside &#x2F;usr&#x2F;local.&lt;&#x2F;li&gt;
&lt;li&gt;you don’t need to add header files to the target sources.  CMake automatically figures out include dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;you can run “&lt;em&gt;make VERBOSE=1”&lt;&#x2F;em&gt; to see the commands make is running during a compile.&lt;&#x2F;li&gt;
&lt;li&gt;cmake -DCMAKE_BUILD_TYPE=Debug can be used to add debugging information (essentially -g).&lt;&#x2F;li&gt;
&lt;li&gt;When developing on your workstation, do the following to build: &lt;em&gt;mkdir build; cd build; cmake ..&#x2F;; make&lt;&#x2F;em&gt; The advantage of running cmake inside a &lt;em&gt;build&lt;&#x2F;em&gt; directory is you can simply wipe the entire build dir to completely reset the build.  Otherwise, the cmake files are mixed up with your source files.&lt;&#x2F;li&gt;
&lt;li&gt;The following is the CMake version of printf – very useful for debugging: &lt;em&gt;message(some_var: ${some_var})&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;ccmake&lt;&#x2F;em&gt; and &lt;em&gt;cmake-gui&lt;&#x2F;em&gt; are useful tools for examining the state of various CMake variables.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Most of these tips are general and have nothing to do with OE, but that is the entire point – using CMake with OE rarely requires you to do anything beyond what you normally do with CMake.  So, if you use CMake correctly, there is usually not a lot more required to cross compile and package your apps in OE.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>PCB Schematics Style Guide</title>
        <published>2014-08-25T00:00:00+00:00</published>
        <updated>2014-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1116/schematics-style/"/>
        <id>https://bec-systems.com/1116/schematics-style/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1116/schematics-style/">&lt;p&gt;As I work at the intersection of hardware and software, I spend a fair amount of time reading schematics for printed circuit boards (PCBs).  I’m astounded at how sloppy most schematics are, and have come up with a few suggestions to consider.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Schematics are not only design entry – &lt;strong&gt;schematics are documentation&lt;&#x2F;strong&gt;.  Unless you are writing all the software, handling all the manufacturing, and debugging all field issues yourself, there will be others who will be using them.  Be considerate.&lt;&#x2F;li&gt;
&lt;li&gt;Not everyone has a D size plotter (even B size printers are fairly rare).  I have a rather large (27“, 2560x1140) monitor, and have seen schematics that I have to zoom in to read.  Schematics should be created such that they &lt;strong&gt;can be printed on letter size paper&lt;&#x2F;strong&gt; (everyone has a letter size printer), and easily read – even by folks in their 60’s.  This is fairly simple – just spend some time breaking large symbols into smaller sections, and use a few more pages.  Even for viewing on a screen, putting &lt;strong&gt;less stuff on each page&lt;&#x2F;strong&gt; makes it easier to scroll through pages.  Most people print out schematics for review or bench work – so having letter size pages makes this possible.&lt;&#x2F;li&gt;
&lt;li&gt;Schematics should be organized to have &lt;strong&gt;one function per page&lt;&#x2F;strong&gt;, or group similar functions on a page.  Don’t intermix power supplies and an audio codec unless they are related.  We realize the importance of organizing software in modules, and a large schematic is really no different.&lt;&#x2F;li&gt;
&lt;li&gt;Keep &lt;strong&gt;all pages the same size&lt;&#x2F;strong&gt;.  When every page is a different size, you can’t easily scroll through pages, or print them out.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Avoid hierarchical schematics&lt;&#x2F;strong&gt;.  For most PCB designs, hierarchical schematics offer no advantage over a flat schematic logically organized on pages.  PCB’s can only be so big, therefore even if you have 20 pages for a schematic, 20 pages is really not all that much, and adding hierarchy to 20 pages just adds complexity and makes them harder to read.  In a sense, your schematic page becomes a “hierarchical block.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Off page references&lt;&#x2F;strong&gt; are the key to making smaller schematic pages work.&lt;&#x2F;li&gt;
&lt;li&gt;Spend a little more time &lt;strong&gt;putting a little art&lt;&#x2F;strong&gt; into your schematic symbols.  If you have a DB-9 connector, and you draw a connector in the shape of a DB-9 (only takes a few more minutes), then you can instantly recognize what it is in the schematic, and it is much quicker to find the circuit you are looking for during debugging sessions.  The same can be said for USB connectors, etc.  In some cases, it may make sense to draw a connector symbol to match how it looks physically, so you can quickly find a pin on the bench without digging out a datasheet.&lt;&#x2F;li&gt;
&lt;li&gt;Schematic text must &lt;strong&gt;be easily searchable&lt;&#x2F;strong&gt;.  I don’t want to install a clunky schematic viewer that only runs on X.XX version of windows just to search for text.  I want to use the PDF reader I already have installed.  Make sure schematics are cleanly exported to PDF, and are easy to search.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I’m sure there are many other ideas – in a brief search, I turned up the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;blog.upverter.com&#x2F;schematic-style-guide&quot;&gt;http:&#x2F;&#x2F;blog.upverter.com&#x2F;schematic-style-guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.k-state.edu&#x2F;ksuedl&#x2F;publications&#x2F;Technote%208%20-%20Guidelines%20for%20Drawing%20Schematics.pdf&quot;&gt;http:&#x2F;&#x2F;www.k-state.edu&#x2F;ksuedl&#x2F;publications&#x2F;Technote%208%20-%20Guidelines%20for%20Drawing%20Schematics.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;electronics.stackexchange.com&#x2F;questions&#x2F;28251&#x2F;rules-and-guidelines-for-drawing-good-schematics&quot;&gt;http:&#x2F;&#x2F;electronics.stackexchange.com&#x2F;questions&#x2F;28251&#x2F;rules-and-guidelines-for-drawing-good-schematics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Library sizes for C vs C++ in an embedded Linux system</title>
        <published>2013-12-18T00:00:00+00:00</published>
        <updated>2013-12-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1107/library-sizes-for-c-vs-c-in-an-embedded-linux-system/"/>
        <id>https://bec-systems.com/1107/library-sizes-for-c-vs-c-in-an-embedded-linux-system/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1107/library-sizes-for-c-vs-c-in-an-embedded-linux-system/">&lt;p&gt;Is the size of the libraries required for C++ (vs C) a concern in Embedded Linux systems?  Most Embedded Linux systems likely include some C++ code, so this is probably not even a decision we need to make in many cases.  However, often there is a need for a small initramfs that is used as part of the boot process (perhaps for software updates) before switching to the main root file system.  In this case, it makes sense to keep the initramfs as small as possible, and we might be concerned here with the size of C++ libraries.&lt;&#x2F;p&gt;
&lt;p&gt;To find out what additional libraries are required when compiling with a C++ compiler vs C, a simple hello-world app was created.  It was then compiled with gcc and g++.  The outputs were then parsed with readelf to determine the required dynamic libraries.  The results are shown below:&lt;&#x2F;p&gt;
&lt;p&gt;C:&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;C++:&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;The sizes of packages for these libraries in an OpenEmbedded build are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;libc: 1.4KiB (libm is inlcuded with libc)&lt;&#x2F;li&gt;
&lt;li&gt;libstdc++6: 256KiB&lt;&#x2F;li&gt;
&lt;li&gt;libgcc1: 204KiB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(The above sizes are compressed, so the actually will be some larger, but are useful for comparison.)&lt;&#x2F;p&gt;
&lt;p&gt;The installed sizes of libstdc++6 and libgcc1 on a ext3 file system are 1.4MiB and 750KiB.&lt;&#x2F;p&gt;
&lt;p&gt;It may also take slightly longer to load a C++ application as there is time required to dynamically load and link additional libraries.  Is an extra 2MiB of libraries a big deal?  It depends on your situation, but should be considered any time you are trying to create a small image.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up an OpenEmbedded Package Feed Server</title>
        <published>2013-12-11T00:00:00+00:00</published>
        <updated>2013-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1085/setting-up-an-openembedded-package-feed-server/"/>
        <id>https://bec-systems.com/1085/setting-up-an-openembedded-package-feed-server/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1085/setting-up-an-openembedded-package-feed-server/">&lt;p&gt;With the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&quot;&gt;BEC OE build template&lt;&#x2F;a&gt;, you can easily set up an opkg feed server that serves up packages from your build directory.  This allows you to easily install new packages during development, without generating and reflashing an entire image.  To use:&lt;&#x2F;p&gt;
&lt;p&gt;On workstation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;edit local.sh, and define MACHINE_IP to point to your target machine, and re-run “source envsetup.sh”.  Alternatively, you can export the MACHINE_IP variable in your environment.&lt;&#x2F;li&gt;
&lt;li&gt;run: oe_setup_feed_server&lt;&#x2F;li&gt;
&lt;li&gt;run: oe_feed_server&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On target system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;opkg update&lt;&#x2F;li&gt;
&lt;li&gt;opkg install &lt;some package&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Opkg will install dependencies, so if you have a complex package, this is so much easier than copying over an opkg file manually, and figuring out you need 6 other packages as dependencies.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why systemd in Embedded Linux Systems?</title>
        <published>2013-12-11T00:00:00+00:00</published>
        <updated>2013-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1098/why-systemd-in-embedded-linux-systems/"/>
        <id>https://bec-systems.com/1098/why-systemd-in-embedded-linux-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1098/why-systemd-in-embedded-linux-systems/">&lt;p&gt;Recently I was asked why use systemd vs sysvinit in embedded systems?  There are many discussions on this, and really most of the reasons people use it for servers and desktops are also valid for embedded systems.  Lennart Poettering’s &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;0pointer.de&#x2F;blog&#x2F;projects&#x2F;why.html&quot;&gt;articles&lt;&#x2F;a&gt; explain very well why you might want to consider systemd.  A few things that rank high on my list:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;systemd systems generally boot must faster than sysvinit systems.&lt;&#x2F;li&gt;
&lt;li&gt;systemd monitors every process it starts, so you know conclusively if your app is still running.&lt;&#x2F;li&gt;
&lt;li&gt;systemd has flexible mechanisms for restarting apps that crash, and rebooting if you get so many restarts in X amount of time.  This is very important in embedded systems where you need to keep things running.&lt;&#x2F;li&gt;
&lt;li&gt;systemd logging (journald) is very flexible.  The stdout of every process that is started by systemd is captured in the journal.  You can also capture kernel messages in the journal.  The end result is you have one place to look for system logs.&lt;&#x2F;li&gt;
&lt;li&gt;systemd has support for &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;0pointer.de&#x2F;blog&#x2F;projects&#x2F;watchdog.html&quot;&gt;watchdog chaining&lt;&#x2F;a&gt; – again, important for many embedded systems.&lt;&#x2F;li&gt;
&lt;li&gt;The systemd dependency mechanism is very flexible.&lt;&#x2F;li&gt;
&lt;li&gt;systemd has tools to debug the init process: systemd-analyze, systemd-cgls, systemd-cgtop, bootchart, pybootchargui, etc.&lt;&#x2F;li&gt;
&lt;li&gt;on demand launch of services can improve boot time and conserve resources.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In summary, with systemd I have more control over the system startup and shutdown, and have better mechanisms to monitor things to make sure they stay running.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Build Template</title>
        <published>2013-06-28T00:00:00+00:00</published>
        <updated>2013-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1047/openembedded-build-template/"/>
        <id>https://bec-systems.com/1047/openembedded-build-template/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1047/openembedded-build-template/">&lt;p&gt;How does one set an OpenEmbedded&#x2F;Yocto&#x2F;Poky&#x2F;Angstrom build? There are many options. Some include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;angstrom-distribution&#x2F;setup-scripts&quot;&gt;Angstrom setup scripts&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.yoctoproject.org&#x2F;cgit&#x2F;cgit.cgi&#x2F;poky&#x2F;&quot;&gt;Poky&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Freescale&#x2F;fsl-community-bsp-platform&quot;&gt;Freescale Community BSP&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;wiki&#x2F;OE-Core_Standalone_Setup&quot;&gt;OpenEmbedded core standalone&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(I’m sure there are many others, feel free to add in comments …)&lt;&#x2F;p&gt;
&lt;p&gt;Over the past years, we’ve supported a number of customers using OpenEmbedded to develop products using various SOC’s. We also try to keep builds going for a number of different systems so that we can continuously evaluate the state of OpenEmbedded and related Embedded Linux technologies. We also needed a standard way to set up builds for customers (some don’t have a lot of experience with OE and Git) that is simple and consistent. What we ended up with is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&quot;&gt;BEC OpenEmbedded build template&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to have a quick entry point into OpenEmbedded that includes the necessary layers for a number of different machines, and automates a number of routine tasks such as installing images to a SD card, setting up a development feed server, etc. The build template is only updated when the build is stable and tested on a number of machines, so it provides a series of stable snapshots of OpenEmbedded and associated layers.&lt;&#x2F;p&gt;
&lt;p&gt;This build template currently tracks the master branches for all the layers used. This gives us a platform to track the latest OE changes. With most projects, that ability to use the features in the latest versions of software outweighs the stability benefits of OpenEmbedded release branches. There are times when the OpenEmbedded project goes through invasive changes (such as the systemd integration), and using the master branches is not practical, so in this case we simply use the last stable snapshot that builds and works. In most cases if there are issues, simply report or fix the issue and wait a week.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps the most controversial decision is the use of Git submodules for including OpenEmbedded layers. The Internet is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;somethingsinistral.net&#x2F;blog&#x2F;git-submodules-are-probably-not-the-answer&#x2F;&quot;&gt;full&lt;&#x2F;a&gt; of &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;Git-Tools-Subtree-Merging&quot;&gt;rants&lt;&#x2F;a&gt; against Git submodules. For heavy developer use, submodules may not be optimal. However, from a user perspective, Git submodules provide a simple mechanism for including external repositories in a project. If most of the submodules (OE layers) won’t be touched (typical OE user scenario), submodules work very well. The fact that Git locks down submodules to a specific commit ensures you are getting exactly what you think you are getting (vs a branch that may have been rebased, modified etc). If the git hash matches, you can be pretty sure it is the same as the last time you built it. This is an important factor in production build systems where you want to be sure of what you are building. Google repo is another option under consideration, but there are still some trade-offs to work through.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, build systems are very personal, and must be customized for your product and development team. The number one requirement for a an Embedded Linux build system is that you can get repeatable builds with a single command. There must be no manual steps where human error can be introduced. This is just one way to accomplish this goal.&lt;&#x2F;p&gt;
&lt;p&gt;(2023-09-05 update: the BEC OE Build template has been replaced by the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoedistro.org&#x2F;&quot;&gt;Yoe Distribution&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OS Containers for Build Systems</title>
        <published>2013-05-08T00:00:00+00:00</published>
        <updated>2013-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1029/os-containers-for-build-systems/"/>
        <id>https://bec-systems.com/1029/os-containers-for-build-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1029/os-containers-for-build-systems/">&lt;p&gt;Since I’ve been running archlinux on some of my systems, one thing I’ve found useful is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;systemd&#x2F;man&#x2F;systemd-nspawn.html&quot;&gt;systemd-nspawn&lt;&#x2F;a&gt;. systemd-nspawn containers (or chroots on non-systemd systems) give you a quick way to install a Linux distribution, that can run inside an existing Linux system.&lt;&#x2F;p&gt;
&lt;p&gt;Some cases where systemd-nspawn containers (referred to as containers in this document) are useful:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;At one point, OpenEmbedded would not build with GCC 4.8 (this is no longer the case with recent versions of OE).  So a Debian or Ubuntu OS container was a quick way to get builds going again.&lt;&#x2F;li&gt;
&lt;li&gt;For product build systems (may live for many years), typically OE will eventually break as you upgrade the workstation distribution.  For projects that need a long-lived OpenEmbedded build system, setting it up in a chroot makes a lot of sense.&lt;&#x2F;li&gt;
&lt;li&gt;Someone might be having a compile or build problem with a distribution you don’t currently have installed.  With containers, you can quickly set up a test distribution to reproduce problems.&lt;&#x2F;li&gt;
&lt;li&gt;I’ve had cases where I need an older version of Qt for a project, but my workstation includes a newer version.  Again, setting up a OS container is sometimes simpler than getting two versions of Qt to dwell together peaceably in the same distribution.&lt;&#x2F;li&gt;
&lt;li&gt;Backing up or replicating your entire build system is very easy – simply rsync the OS container directory to another machine.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;So the solution is to select a relatively stable, long-lived distribution to host your product builds. Debian is good choice.  Because the container is simply a directory in the host workstation filesystem, you can use host workstation tools (editors, git, etc) directly in the container filesystem.  The only thing you need to use the chroot for is the actual building.  If you make sure the user ID is the same between your workstation and nspawn container, then permissions are seamless – you can easily access files in the container from the context of your host workstation.&lt;&#x2F;p&gt;
&lt;p&gt;To set up a nspawn-container:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Install debootstrap.  On arch systems, this needs to be obtained for the AUR.&lt;&#x2F;li&gt;
&lt;li&gt;host: &lt;em&gt;sudo debootstrap --arch=amd64 wheezy ~&#x2F;debian-wheezy&#x2F;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;host: &lt;em&gt;sudo systemd-nspawn -D ~&#x2F;debian-wheezy&#x2F;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;container: &lt;em&gt;apt-get update &amp;amp;&amp;amp; apt-get install ssh&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;container: &lt;em&gt;edit &#x2F;etc&#x2F;ssh&#x2F;sshd_config, and set port to something other than 22 (23 in this example)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;container: &lt;em&gt;&#x2F;etc&#x2F;init.d&#x2F;ssh start&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;(This &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;systemd&#x2F;man&#x2F;systemd-nspawn.html&quot;&gt;systemd-nspawn&lt;&#x2F;a&gt; man page gives examples for setting up other distributions.)&lt;&#x2F;p&gt;
&lt;p&gt;To set up a user in your container:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;host: id&lt;&#x2F;li&gt;
&lt;li&gt;will return something like: uid=1000(cbrake) gid=100(users) …&lt;&#x2F;li&gt;
&lt;li&gt;container: adduser --uid 1000 -gid 100 cbrake&lt;&#x2F;li&gt;
&lt;li&gt;host: ssh-copy-id -p 23 localhost (will copy public key to container)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now, on the host system, you can simply “&lt;em&gt;ssh -p23 localhost”&lt;&#x2F;em&gt; any time you want to log into the container.  Soft links between the project workspace on the host system, and the container can also make shifting between the two easier.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative way to start the container once its set up is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;sudo systemd-nspawn -D ~&#x2F;debian-wheezy &#x2F;sbin&#x2F;init&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Its also handy to make the shell prompt in the container slightly different than the host OS so that you can easily tell the difference.  To accomplish this, add the following to ~&#x2F;.profile in the container OS:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;export PS1=“[\u@wheezy \w]\$ “&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To create a service that starts your container, put something like the following in &#x2F;lib&#x2F;systemd&#x2F;system&#x2F;debian-wheezy.service&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Debian Wheezy
[Service]
ExecStart=&#x2F;usr&#x2F;bin&#x2F;systemd-nspawn -D &#x2F;scratch&#x2F;debian-wheezy&#x2F; &#x2F;sbin&#x2F;init 3
KillMode=process
[Install]
WantedBy=multi-user.target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hopefully this gives you a quick overview of how OS containers can be set up, and used in your OpenEmbedded build systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git submodules can now track branches</title>
        <published>2013-04-22T00:00:00+00:00</published>
        <updated>2013-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1020/git-submodules-can-now-track-branches/"/>
        <id>https://bec-systems.com/1020/git-submodules-can-now-track-branches/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1020/git-submodules-can-now-track-branches/">&lt;p&gt;As of version 1.8.2, Git submodules can now track branches instead of specific commits.  This is good news as in many cases, this is exactly the behavior we want.  However, Git submodules are still not as flexible as Google &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;git-repo&#x2F;&quot;&gt;repo&lt;&#x2F;a&gt;, but since submodules are built into Git, the submodule command is a good solution in many cases.&lt;&#x2F;p&gt;
&lt;p&gt;The “&lt;em&gt;git submodule update --remote&lt;&#x2F;em&gt;” command is the key to tracking branches with submodules.   The following is from the Git man pages:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;--remote
This option is only valid for the update command. Instead of using the superproject’s recorded SHA-1 to update the submodule, use the status of the submodule’s remote tracking branch. The remote used is branch’s remote (branch.&lt;name&gt;.remote), defaulting to origin. &lt;strong&gt;The remote branch used defaults to master, but the branch name may be overridden by setting the submodule.&lt;name&gt;.branch option in either .gitmodules&lt;&#x2F;strong&gt; or .git&#x2F;config (with .git&#x2F;config taking precedence).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;This works for any of the supported update procedures (--checkout, --rebase, etc.). The only change is the source of the target SHA-1. For example, submodule update --remote --merge will merge upstream submodule changes into the submodules, while submodule update --merge will merge superproject gitlink changes into the submodules.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;In order to ensure a current tracking branch state, update --remote fetches the submodule’s remote repository before calculating the SHA-1. If you don’t want to fetch, you should use submodule update --remote --no-fetch.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So, if you already have a Git submodule set up, its a simple matter to run &lt;em&gt;git submodule update --remote&lt;&#x2F;em&gt; to update the submodule to the latest master branch.  If you want a different branch, simple edit &lt;em&gt;.gitconfig&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[submodule &amp;quot;meta-bec&amp;quot;]
   path = meta-bec
   url = git@github.com:cbrake&#x2F;meta-bec.git
   branch = test
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, if you run *git submodule update --remote,*Git will update the &lt;em&gt;meta-bec&lt;&#x2F;em&gt; submodule to the latest on the &lt;em&gt;test&lt;&#x2F;em&gt; branch.&lt;&#x2F;p&gt;
&lt;p&gt;This functionality is purely a convenience feature in the &lt;em&gt;submodule update&lt;&#x2F;em&gt; command.  In the actual repository, Git still stores submodules pointed to a particular commit.  The same thing could be accomplished with something like &lt;em&gt;git foreach “git fetch &amp;amp;&amp;amp; git checkout test”&lt;&#x2F;em&gt;.  The branch option in .gitmodules functions more as documentation and convenience.  It is very handy to be able to look at .gitmodules and quickly determine that submodule X is tracking branch Y.  Normally, this would have to be documented elsewhere, or figured out in some other way.  Also, for build systems where you want the build to always track the production branches of various projects, &lt;em&gt;update --remote&lt;&#x2F;em&gt; gives you a convenient way to update the build tree.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick way to share files from any directory</title>
        <published>2013-01-22T00:00:00+00:00</published>
        <updated>2013-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1015/a-quick-way-to-share-files-from-any-directory/"/>
        <id>https://bec-systems.com/1015/a-quick-way-to-share-files-from-any-directory/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1015/a-quick-way-to-share-files-from-any-directory/">&lt;p&gt;Did you ever need a quick way to share files from a directory on your computer?  Or perhaps transfer a large file to another person?  With &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;nodejs.org&#x2F;&quot;&gt;nodejs&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;expressjs.com&#x2F;&quot;&gt;express&lt;&#x2F;a&gt;, you can easily set up a temporary web server that allows users to browse and access a list of files in a directory.  For convenience, I created a simple &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;http-file-server&quot;&gt;github project&lt;&#x2F;a&gt; that can be cloned into any directory, and then a server started in a matter of seconds.  Yes, you could upload files to a server, or share them with a file sharing service, but if you can expose a random port on your computer to the person who needs the files, then this is faster, and does not require any intermediate steps.  Check out &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;http-file-server&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;http-file-server&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Source Mirrors</title>
        <published>2013-01-07T00:00:00+00:00</published>
        <updated>2013-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1010/openembedded-source-mirrors/"/>
        <id>https://bec-systems.com/1010/openembedded-source-mirrors/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1010/openembedded-source-mirrors/">&lt;p&gt;When using OpenEmbedded for product development, there are several reasons you may want to consider setting up a source mirror for your OpenEmbedded build:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;over time, sources disappear from download locations&lt;&#x2F;li&gt;
&lt;li&gt;various servers for source packages may be off-line at the time a build is run&lt;&#x2F;li&gt;
&lt;li&gt;some servers may be very slow, which slows down your build&lt;&#x2F;li&gt;
&lt;li&gt;occasionally the checksums of a source package will change&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For a production build system, you want the build to be reliable and consistent, so this means not depending on 3rd party web sites&#x2F;servers for a clean build to complete.  Fortunately, OpenEmbedded makes it easy to set up a source mirror with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;1.0&#x2F;poky-ref-manual&#x2F;poky-ref-manual.html#idm1091472&quot;&gt;PREMIRRORS&lt;&#x2F;a&gt; variable. When bitbake tries to fetch source code, it tries PREMIRRORS, the upstream source, and then MIRRORS.  There are several advantages to using a PREMIRROR variable over a MIRROR for your source mirror:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;your source mirror will be used first, thus slow web sites are not an issue&lt;&#x2F;li&gt;
&lt;li&gt;if the checksums of the package change, the build will not fail because its still using the original source package from the mirror.  You are guaranteed to be always using the same source package.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Setting up a source mirror is as simple as copying the contents of your downloads directory to a web server, and then populating the following variable in local.conf:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;PREMIRRORS_prepend = &amp;quot;\
     git:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n \
     ftp:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n \
     http:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n \
     https:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Poky reference manual has more &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;1.0&#x2F;poky-ref-manual&#x2F;poky-ref-manual.html#idm1091472&quot;&gt;details&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Perisistent device names for USB serial ports</title>
        <published>2012-12-19T00:00:00+00:00</published>
        <updated>2012-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1004/perisistent-device-names-usb-serial-ports/"/>
        <id>https://bec-systems.com/1004/perisistent-device-names-usb-serial-ports/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1004/perisistent-device-names-usb-serial-ports/">&lt;p&gt;Currently, my workstation has &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;usbgear.com&#x2F;USB2-8COM-M.html&quot;&gt;two 8-port USB&amp;lt;-&amp;gt;RS232 devices&lt;&#x2F;a&gt;, one &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;usbgear.com&#x2F;USB-2COMi-M.html&quot;&gt;dual port USB&amp;lt;-&amp;gt;RS422&#x2F;RS485 adapter&lt;&#x2F;a&gt;, and several single port adapters such as the very useful &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;shop.moderndevice.com&#x2F;products&#x2F;bub_ii&quot;&gt;BUBII&lt;&#x2F;a&gt;.  So with around 20 USB-&amp;gt;serial devices, figuring out which &#x2F;dev&#x2F;ttyUSBx entry corresponds to which port is not really practical.  However, with udev in Linux, you can easily give static names to each device.  This is especially convenient to do with FTDI devices because each FTDI device has a serial number.  In devices such as the 8-port RS232 adapter, there are 4, 2-port FTDI chips.  I could not find a serial number available in the adapter with a Prolific IC, so I would avoid those until that is sorted.&lt;&#x2F;p&gt;
&lt;p&gt;udevadm can be used to discover the serial number for a FTDI device:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;udevadm info --attribute-walk -n &#x2F;dev&#x2F;ttyUSB0|grep serial
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After the serial number is known, rules can be created in the &lt;em&gt;&#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;99-usb-serial.rules&lt;&#x2F;em&gt; as shown in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;4337154&quot;&gt;this example&lt;&#x2F;a&gt;.  Now, serial ports can be accessed using convenient names such as &lt;em&gt;&#x2F;dev&#x2F;ttyUSB_beagle&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick way to set up an OpenEmbedded feed server</title>
        <published>2012-12-08T00:00:00+00:00</published>
        <updated>2012-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/988/a-quick-way-to-set-up-an-openembedded-feed-server/"/>
        <id>https://bec-systems.com/988/a-quick-way-to-set-up-an-openembedded-feed-server/</id>
        
        <content type="html" xml:base="https://bec-systems.com/988/a-quick-way-to-set-up-an-openembedded-feed-server/">&lt;p&gt;During development with OpenEmbedded (oe-core, meta-oe, meta-angstrom), I often find it useful to set up a feed server so that packages can quickly be installed on the target system without manually copying them over or building a new image.  One way to do this is copy your deploy&#x2F;ipk directory to an existing web server (perhaps Apache running on your workstation), or configure Apache to point at your OE build directory, etc.  But, it might be more convenient if your build system could directly create an opkg feed with no extra configuration.  In the below example, we use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;nodejs.org&#x2F;&quot;&gt;node.js&lt;&#x2F;a&gt; + &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;expressjs.com&#x2F;&quot;&gt;express.js&lt;&#x2F;a&gt; to create a feed server (basically just a web server that serves up the ipk files).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;tools&#x2F;feed-server&#x2F;app.js:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;&#x2F; nodejs script to start a http server with the feed from this directory
&#x2F;&#x2F; default is port 4000
var express = require(&amp;#39;express&amp;#39;)
var app = express()
app.use(&amp;#39;&#x2F;&amp;#39;, express.static(__dirname +
   &amp;#39;&#x2F;..&#x2F;..&#x2F;build&#x2F;tmp-angstrom_next-eglibc&#x2F;deploy&#x2F;ipk&#x2F;&amp;#39;))
app.use(&amp;#39;&#x2F;&amp;#39;, express.directory(__dirname +
   &amp;#39;&#x2F;..&#x2F;..&#x2F;build&#x2F;tmp-angstrom_next-eglibc&#x2F;deploy&#x2F;ipk&#x2F;&amp;#39;))
console.log(&amp;quot;feed server started on port 4000&amp;quot;)
app.listen(4000)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;express.directory&lt;&#x2F;em&gt; function is used to create a directory listing that can be browsed.  With most other web servers, at least this much code is required just for configuration.  With node.js, this is the code to create an entire server from scratch!  This node.js app can be started with a bash function in the environment:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;function oe_feed_server()
{
  cd $OE_BASE
  bitbake package-index
  node tools&#x2F;feed-server&#x2F;app.js
  cd -
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;package-index&lt;&#x2F;em&gt; target is used to rebuild the index files that list the available packages.&lt;&#x2F;p&gt;
&lt;p&gt;On the target system, the &#x2F;etc&#x2F;opkg configuration files must be modified to point to the feed server, and then you can run:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;opkg update; opkg install &amp;lt;package&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An exmaple build environement with this integrated is located:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;23352b9a43c60d67070abe5ac001aba9a9ac5cc4&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;23352b9a43c60d67070abe5ac001aba9a9ac5cc4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;6baceb8b1e4477ccfd03aa553a5fcf501b398196&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;6baceb8b1e4477ccfd03aa553a5fcf501b398196&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It might be argued that it is just as easy or easier to set up a more conventional web server.  However, the benefit of node.js is that it is a full blown programming environment.  You can quickly extend it to provide a web interface, perhaps add functionality to automatically push updated opkg configuration files to the target system that point to your feed server, etc.  It is much more than just a web server.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting the root password in an OpenEmbedded image</title>
        <published>2012-12-05T00:00:00+00:00</published>
        <updated>2012-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/967/setting-the-root-password-in-an-openembedded-image/"/>
        <id>https://bec-systems.com/967/setting-the-root-password-in-an-openembedded-image/</id>
        
        <content type="html" xml:base="https://bec-systems.com/967/setting-the-root-password-in-an-openembedded-image/">&lt;p&gt;During development, often a blank root password is used for the embedded Linux target system.  However, when deploying an embedded Linux system, often there is a requirement to set the root password to something non-obvious.  One way to do this is boot the system, and change the password using the passwd command.  Then copy the password hash from the &#x2F;etc&#x2F;shadow file into the below line in your image recipe.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ROOTFS_POSTPROCESS_COMMAND += &amp;quot;\
sed &amp;#39;s%^root:[^:]*:%root:password_hash_from_etc_shadow:%&amp;#39; \
&amp;lt; ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow \
&amp;gt; ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow.new;\
mv ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow.new ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow ;&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The ROOTFS_POSTPROCESS_COMMAND is useful for simple modifications like this to the rootfs image.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded: configuring openssh to allow a blank password</title>
        <published>2012-12-05T00:00:00+00:00</published>
        <updated>2012-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/978/openembedded-configuring-openssh-to-allow-blank-password/"/>
        <id>https://bec-systems.com/978/openembedded-configuring-openssh-to-allow-blank-password/</id>
        
        <content type="html" xml:base="https://bec-systems.com/978/openembedded-configuring-openssh-to-allow-blank-password/">&lt;p&gt;Noticed the following when browsing around in the OpenEmbedded sources the other day:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ROOTFS_POSTPROCESS_COMMAND += &amp;quot;openssh_allow_empty_password ;&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows a blank password for development, which is conveient for running ssh&#x2F;scp commands to the device.  The above can be placed in an image recipe.&lt;&#x2F;p&gt;
&lt;p&gt;The command modifies the PermitEmptyPasswords config option in &#x2F;etc&#x2F;ssh&#x2F;sshd_config or &#x2F;etc&#x2F;default&#x2F;dropbear.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running a reboot cycle test shell script with systemd</title>
        <published>2012-08-29T00:00:00+00:00</published>
        <updated>2012-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/942/running-a-reboot-cycle-test-shell-script-with-systemd/"/>
        <id>https://bec-systems.com/942/running-a-reboot-cycle-test-shell-script-with-systemd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/942/running-a-reboot-cycle-test-shell-script-with-systemd/">&lt;p&gt;One of the easiest ways to stress test an embedded Linux system is to continuously reboot the system. Booting is a difficult activity for a Linux system (similar to waking up in the morning). The CPU is maxed out. There are a lot of things happening in parallel. Software is initializing. There is a lot of filesystem activity. Often, if there is an instability in the system (and especially the filesystem), continuously rebooting will expose it.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we use systemd for most new systems, we need to run a simple script X seconds after the system boots to increment the boot count, and reboot. This is the classic domain of a shell script. However, for a simple task like this, it’s a little cumbersome to create a seperate shell script and then call this script from a systemd unit. The following is a way to embed the script directly in a systemd unit.&lt;&#x2F;p&gt;
&lt;p&gt;Put the following in: &lt;em&gt;&#x2F;lib&#x2F;systemd&#x2F;system&#x2F;cycletest.service&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Reboots unit after 30s

[Service]
StandardOutput=syslog+console
ExecStart=&#x2F;bin&#x2F;sh -c &amp;quot;\
test -f &#x2F;cycle-count || echo 0 &amp;gt; &#x2F;cycle-count;\
echo &amp;#39;starting cycletest&amp;#39;;\
sleep 30;\
expr `cat &#x2F;cycle-count` + 1 &amp;gt; &#x2F;cycle-count;\
systemctl reboot;\
&amp;quot;

[Install]
WantedBy=multi-user.target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To install and start the script:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;systemctl daemon-reload&lt;&#x2F;li&gt;
&lt;li&gt;systemctl enable cycletest.service (enable the service to start on reboot)&lt;&#x2F;li&gt;
&lt;li&gt;systemctl start cycletest.service (start the service, should reboot in 30s)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bitbake has a new way of displaying build status</title>
        <published>2012-08-29T00:00:00+00:00</published>
        <updated>2012-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/958/bitbake-has-a-new-way-of-displaying-build-status/"/>
        <id>https://bec-systems.com/958/bitbake-has-a-new-way-of-displaying-build-status/</id>
        
        <content type="html" xml:base="https://bec-systems.com/958/bitbake-has-a-new-way-of-displaying-build-status/">&lt;p&gt;Now instead of displaying a scrolling log, bitbake will display a simple output that lists which tasks it is working on at the moment:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;﻿﻿Currently 4 running tasks (185 of 3093):
0: gmp-native-5.0.5-r0 do_configure (pid 22919)
1: lzo-native-2.06-r1 do_configure (pid 27103)
2: expat-native-2.1.0-r0 do_compile (pid 7463)
3: ncurses-native-5.9-r10.1 do_compile (pid 9820)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This really allows for a clear view of how the parallel threads option (BB_NUMBER_THEADS) in bitbake works.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mounting a UBIFS partition using systemd</title>
        <published>2012-08-16T00:00:00+00:00</published>
        <updated>2012-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/917/mounting-a-ubifs-partition-using-systemd/"/>
        <id>https://bec-systems.com/917/mounting-a-ubifs-partition-using-systemd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/917/mounting-a-ubifs-partition-using-systemd/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.freedesktop.org&#x2F;wiki&#x2F;Software&#x2F;systemd&#x2F;&quot;&gt;Systemd&lt;&#x2F;a&gt; is becoming the defacto system and service manager for Linux, replacing the SysV init scripts.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.angstrom-distribution.org&#x2F;&quot;&gt;Angstrom distribution&lt;&#x2F;a&gt; has supported systemd for some time now. Recently, I needed to mount a UBIFS filesystem in one of my projects.  The main application is being started with systemd, so it seemed like a good fit to also use systemd to mount a data partition needed by the application. Systemd can use entries from &#x2F;etc&#x2F;fstab, but one additional wrinkle in this system is that I also wanted to run the UBI attach in a controlled way. This can be done with a kernel command line argument, but there are times in this system where we will want to format the data partition, so this requires a detach&#x2F;attach operation.&lt;&#x2F;p&gt;
&lt;p&gt;The resulting systemd units are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;data.mount﻿﻿&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Mount data partition
Requires=data-attach.service
After=data-attach.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;[Mount]
What=ubi1:data
Where=&#x2F;data
Type=ubifs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;data-attach.service&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Attach data ubi partition

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=&#x2F;usr&#x2F;sbin&#x2F;ubiattach &#x2F;dev&#x2F;ubi_ctrl -m 6
ExecStop=&#x2F;usr&#x2F;sbin&#x2F;ubidetach &#x2F;dev&#x2F;ubi_ctrl -m 6
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;add the following to &lt;em&gt;&lt;strong&gt;my-application.service&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Wants=data.mount
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The only real problem I ran into is the “After” statement in the &lt;em&gt;data.mount&lt;&#x2F;em&gt; unit.  It turns out that the mount will run before the attach operation is finished unless this is included.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;RemainAfterExit&lt;&#x2F;em&gt; seems to be required so that &lt;em&gt;ExecStop&lt;&#x2F;em&gt; can be run when the unit is stopped.&lt;&#x2F;p&gt;
&lt;p&gt;(There may be a better ways to do all this, so comments are welcome!)&lt;&#x2F;p&gt;
&lt;p&gt;One of the benefits of systemd is that everything is very controlled.  If the dependencies are specified properly, there are no race conditions.  Additionally, if you need to manage units (services, mounts, etc) from a program, it is much easier to check the states as everything is very consistent.  For example, if you want to query the state of a unit, the *systemctl show &lt;unit&gt;*command will return easily parsed output (as shown below):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;...
Before=umount.target
After=data-attach.service systemd-journald.socket -.mount
Description=Mount data partition
LoadState=loaded
ActiveState=active
SubState=mounted
FragmentPath=&#x2F;lib&#x2F;systemd&#x2F;system&#x2F;data.mount
UnitFileState=static
InactiveExitTimestamp=Thu, 01 Jan 1970 00:00:17 +0000
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the data-attach service is stopped, systemd automatically unmounts the data partition first – very nice!&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully this example illustrates how to do simple tasks in systemd.  It appears that instead of having a complex script or program to initialize a system, the systemd “way” is to create a number of small units that get connected with dependencies.  This seems like a much more controlled and flexible approach.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Review of Graphical Application Solutions for Embedded Linux Systems</title>
        <published>2012-08-07T00:00:00+00:00</published>
        <updated>2012-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/890/graphical-solutions-for-embedded-linux/"/>
        <id>https://bec-systems.com/890/graphical-solutions-for-embedded-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/890/graphical-solutions-for-embedded-linux/">&lt;p&gt;One of the decisions we face when building Embedded Linux systems is what components to use. With Open Source software, there is often more than one good option. Graphical libraries are no exception. In this article, we’ll examine GTK+, Qt, EFL, Android, and HTML&#x2F;Javascript.&lt;&#x2F;p&gt;
&lt;p&gt;There are many factors that go into a choice like this, but some of them are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Does the application need to run on Windows or MacOS?&lt;&#x2F;li&gt;
&lt;li&gt;Does the GUI need to be viewed remotely over a network?&lt;&#x2F;li&gt;
&lt;li&gt;Are dynamic effects (think iPhone) desired?&lt;&#x2F;li&gt;
&lt;li&gt;Does the application need to run on low end CPU’s (ones without a GPU)?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Putting some effort into selecting the right GUI technology is important for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Most of the development effort for the product will likely be in the graphical application, so it makes sense to maximize the productivity of the application developers.  Typically there might be 3-10 application developers on a project for every system software developer.&lt;&#x2F;li&gt;
&lt;li&gt;You want a technology that will scale with new revisions and improvements of the product.&lt;&#x2F;li&gt;
&lt;li&gt;You want a technology that will be supported and improved long term.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With Open Source software, things are always changing.  Leading technologies change.  This can be illustrated by following Intel’s support for their open source software platforms.  While some of this may be driven by politics, we can also see clear technical and licensing reasons why these shifts were made.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Moblin (GTK+), became public around 2007, merged into MeeGo in 2010&lt;&#x2F;li&gt;
&lt;li&gt;MeeGo (Qt), announced in 2010-02, cancelled 2011-09&lt;&#x2F;li&gt;
&lt;li&gt;Tizen (HTML&#x2F;Javascript, EFL), announced in 2011-09&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can see similar shifts in other companies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Nokia started with GTK+ as the GUI technology for their tablet computers, and then shifted to Qt&lt;&#x2F;li&gt;
&lt;li&gt;Samsung has been using GTK+ on top of DirectFB, and now is moving toward EFL&#x2F;HTML&#x2F;Javascript for some phones&lt;&#x2F;li&gt;
&lt;li&gt;Many phone manufactures are producing Android products&lt;&#x2F;li&gt;
&lt;li&gt;Palm moved from a proprietary GUI to HTML in webOS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;gtk&quot;&gt;GTK+&lt;&#x2F;h2&gt;
&lt;p&gt;GTK+ is part of the GNOME desktop project and is perhaps the most used graphical library for desktop Linux applications, and in the past has been very popular in Embedded systems.  Nokia has invested heavily in GTK+ in the past with its early tablet products (N770, N800, N900, etc).  However, with the advent of the iPhone and faster processors with GPUs, everything has changed.  The standard is now dynamic GUI’s with sliding effects, etc.  The Clutter project is a library that can be used to build dynamic GUIs and fits in with the GNOME stack.  GTK+ supports Windows and MacOS, but probably not as well as Qt.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qt&quot;&gt;Qt&lt;&#x2F;h2&gt;
&lt;p&gt;Qt is a very mature project that is also extensively used for desktop projects, and recently is being used on some of Nokia’s phones.  Qt was originally developed by the Norwegian company Trolltech. Originally, Qt was only offered with either a proprietary license or the GPL license.  This meant if you wanted to write a proprietary application using Qt, you had to purchase Trolltech’s commercial license. This factor alone probably made GTK+ a much more popular solution for many years for Embedded Linux GUI’s, including most cell phone stacks.  In 2008, Trolltech was acquired by Nokia, and shortly after that, Qt was offered under the LPGL license, giving it the same license as GTK+.&lt;&#x2F;p&gt;
&lt;p&gt;One of Qt’s compelling features introduced in Qt 4.7 is its QML (or Qt Quick) technology.  This allows you to write declarative GUI’s in a Javascript like syntax with many automatic bindings.  There is good support for dynamic operations like sliding effects, and the performance is reasonable, even on low-end systems without a GPU.&lt;&#x2F;p&gt;
&lt;p&gt;In the future, Qt 5.0 will require OpenGL, and hence be relegated to high end ARM CPU’s with a GPU, or desktop systems.&lt;&#x2F;p&gt;
&lt;p&gt;Qt’s cross platform support is excellent, and provides good native support for Linux, MacOS, and Windows.&lt;&#x2F;p&gt;
&lt;p&gt;Recently, Nokia has made efforts to set up Qt as more of a community project, instead of retaining exclusive control over it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;efl&quot;&gt;EFL&lt;&#x2F;h2&gt;
&lt;p&gt;EFL (Enlightenment Foundation Libraries) is a project that started out as the Enlightenment window manager, and grew into a set of general purpose libraries.  It claims to be to be more efficient than GTK+ and Qt, and work with or without hardware acceleration.  Recently, EFL seems to have garnered the commercial interest of Samsung, Intel, and others involved in the Tizen project.  According to a presentation by Carsten Haitzler (one of EFL’s founders and developers), Samsung was using GTK+ and DirectFB, but switched to EFL after seeing the performance.  Perhaps the most compelling story for EFL is the high performance over a range of hardware capabilities (from simple phones with low end processors, to high end smart-phones running OpenGL).  Parts of EFL are also used in the commercial GUI FancyPants.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;android&quot;&gt;Android&lt;&#x2F;h2&gt;
&lt;p&gt;Android is an interesting GUI solution, especially as many developers have experience working on Android applications.  Android now seems to be used in many applications where Windows CE was used in the past, probably due to its polished application development tool-set.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;html-javascript&quot;&gt;HTML&#x2F;Javascript&lt;&#x2F;h2&gt;
&lt;p&gt;Application development with HTML and Javascript is one of the more interesting developments because many embedded systems are headless (don’t have a local display). Couple this with the fact that many users now have smartphones or tablets readily available, and it may make sense to simply use an external device for displaying the UI.  There is often a requirement for accessing the UI of a device remotely, and in this case, HTML&#x2F;Javascript works very well.  If the UI needs to be displayed locally, then a fairly powerful CPU is required (an ARM Cortex-A8, etc) to run a modern web browser.  If there is no physical display on the device, and the UI is accessed remotely on a computer or mobile device, then a less powerful CPU is required because the embedded device does not actually have to do any of the rendering.  HTML&#x2F;Javascript also has the benefit that it is a very popular technology, thus there are many experienced developers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Each of the above technologies has benefits and drawbacks.  Understanding your project’s requirements, and what each solution offers is key to making the best decision.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Linux Kernel Tracing Tutorial</title>
        <published>2012-01-31T00:00:00+00:00</published>
        <updated>2012-01-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/865/linux-tracing-tutorial/"/>
        <id>https://bec-systems.com/865/linux-tracing-tutorial/</id>
        
        <content type="html" xml:base="https://bec-systems.com/865/linux-tracing-tutorial/">&lt;p&gt;The Linux kernel has a fairly extensive tracing infrastructure that is quite useful for debugging.  There are a number of things you can do with tracing, but the focus of this article will be the traditional printk type debugging we often end up doing to trace initialization issues with a driver.  The following links provide additional information on the linux kernel tracing infrastructure:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;865&#x2F;linux-tracing-tutorial&#x2F;%EF%BB%BFhttp:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git;a=tree;f=Documentation&#x2F;trace&quot;&gt;﻿&lt;&#x2F;a&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git;a=tree;f=Documentation&#x2F;trace&quot;&gt;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git;a=tree;f=Documentation&#x2F;trace&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Debugging the kernel using Ftrace - part 1: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;365835&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;365835&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Debugging the kernel using Ftrace - part 2: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;366796&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;366796&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Secrets of the Ftrace function tracer: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;370423&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;370423&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;elinux.org&#x2F;Kernel_Trace_Systems&quot;&gt;http:&#x2F;&#x2F;elinux.org&#x2F;Kernel_Trace_Systems&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this example, I am working on a new audio driver.  The typical experience with a new driver is that you install it and nothing happens because something is not registered correctly with the Linux driver model.  So, the first thing I do is start with with the platform_device_add() function in my drivers init function.  To observe the kernel activity around the kernel platform code, I can do the following:&lt;&#x2F;p&gt;
&lt;p&gt;﻿﻿cd &#x2F;sys&#x2F;kernel&#x2F;debug&#x2F;tracing&#x2F;
echo 0 &amp;gt; tracing_on﻿ (keep trace from filling up until we set filter)
echo function_graph &amp;gt; current_tracer
echo platform* &amp;gt; set_ftrace_filter
echo 1 &amp;gt; tracing_on
cat trace_pipe (leave running in a different shell)
&lt;insmod my driver&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After executing the above, we see the following.  For this example, trace_pipe is preferred because the trace is then emptied and only new information is shown.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;0) + 30.518 us   |  platform_device_alloc();
0)               |  platform_device_add() {
0)   0.000 us    |    platform_uevent();
0) + 30.518 us   |  platform_uevent();
0)   0.000 us    |  platform_uevent();
0) + 30.518 us   |    platform_match();
0) + 30.518 us   |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();

...

0) + 30.518 us   |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();
0) ! 3936.767 us |  }
0) + 30.518 us   |  platform_uevent();
0) + 30.518 us   |  platform_device_alloc();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the above, I can conclude that the platform_match() is not succeeding, because I would expect some more activity.  At this point I chose to add a printk:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a&#x2F;drivers&#x2F;base&#x2F;platform.c b&#x2F;drivers&#x2F;base&#x2F;platform.c
index 7a24895..f9ce0c7 100644
--- a&#x2F;drivers&#x2F;base&#x2F;platform.c
+++ b&#x2F;drivers&#x2F;base&#x2F;platform.c
@@ -662,6 +662,8 @@ static int platform_match(struct device *dev, struct device_driver *drv)
        struct platform_device *pdev = to_platform_device(dev);
        struct platform_driver *pdrv = to_platform_driver(drv);

+       trace_printk(&amp;quot;pdev-&amp;gt;name = %s, drv-&amp;gt;name = %s&amp;quot;, pdev-&amp;gt;name, drv-&amp;gt;name);
+
        &#x2F;* Attempt an OF style match first *&#x2F;
        if (of_driver_match_device(dev, drv))
                return 1;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, if I re-run the trace, I see the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = davinci_emac *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = snd-soc-dummy *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = soc-audio *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = omap-pcm-audio *&#x2F;
 0)   0.000 us    |    }
 0) ! 4241.943 us |  } &#x2F;* platform_device_add *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the above, it looks like we have a simple mismatch between “soc_audio” and “soc-audio.”  Fixing this problem, and re-installing the module, we now have:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = snd-soc-dummy *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = soc-audio *&#x2F;
 0)   0.000 us    |    }
 0) + 91.553 us   |    platform_drv_probe();
 0) ! 4241.943 us |  } &#x2F;* platform_device_add *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can see that the names match, and the probe function is now being called.  At this point, we may want to turn on tracing of some additional functions to try to determine what is happening next.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;platform* snd* mydriver*&amp;quot; &amp;gt; set_ftrace_filter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the result:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = snd-soc-dummy *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = soc-audio *&#x2F;
 0) + 30.517 us   |    }
 0)               |    platform_drv_probe() {
 0)               |      snd_soc_register_card() {
 0) + 30.518 us   |        snd_soc_instantiate_cards();
 0) ! 17852.78 us |      }
 0) ! 17883.30 us |    }
 0) ! 22125.24 us |  } &#x2F;* platform_device_add *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the above additional information, we can continue to learn more about the flow through the kernel.&lt;&#x2F;p&gt;
&lt;p&gt;While all of the above could have been done with printk’s, it would have been more time consuming.  The kernel function tracing capabilities allow us to quickly get a high level view of the flow through the kernel without manually adding a bunch of printk statements.  The kernel tracing features are completely contained in the kernel without requiring additional user space utilities which makes it very convenient to use in embedded systems.  The low overhead is also important in resource constrained embedded systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The easy way to get serial terminal in Linux</title>
        <published>2012-01-26T00:00:00+00:00</published>
        <updated>2012-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/859/the-easy-way-to-get-serial-terminal-in-linux/"/>
        <id>https://bec-systems.com/859/the-easy-way-to-get-serial-terminal-in-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/859/the-easy-way-to-get-serial-terminal-in-linux/">&lt;p&gt;When doing embedded Linux development, most of us spend out time tethered to a target system with a serial cable, which is used for a serial console.  Minicom is the defacto serial terminal software for Linux.  However, Minicom is a little fussy in that you typically have to set it up for each port you want to use.  This is no big deal, but is generally difficult for new users to understand, and yet another hurdle.  And with 8-port USB-&amp;gt;serial adapters, I have a lot of ports to set up.&lt;&#x2F;p&gt;
&lt;p&gt;Just recently, I discovered that screen can be used as a serial terminal program:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;screen &#x2F;dev&#x2F;ttyUSB0 115200
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A few notes on using:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;to exit screen: Ctrl-a k&lt;&#x2F;li&gt;
&lt;li&gt;to write a hardcopy of the screen image: Ctrl-a h&lt;&#x2F;li&gt;
&lt;li&gt;to get help: Ctrl-?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All the neat features of screen are two numerous to list here, but one more that I’ll point out is the scrollback&#x2F;copy feature (activated by Ctrl-a [ ).  This allows you to scroll back and the navigation works much like VI – what could be nicer?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Verizon UML290 and Sprint U600 USB Modems in Embedded Systems</title>
        <published>2011-03-31T00:00:00+00:00</published>
        <updated>2011-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/842/verizon-uml290-and-sprint-u600-usb-modems-in-embedded-systems/"/>
        <id>https://bec-systems.com/842/verizon-uml290-and-sprint-u600-usb-modems-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/842/verizon-uml290-and-sprint-u600-usb-modems-in-embedded-systems/">&lt;p&gt;Recently I tested support for the Verizon UML290 and Sprint U600 USB Cellular modems in an embedded Linux system.  Both modems support 3G and 4G networks, but only the 3G modes were tested due to lack of 4G coverage at the testing location.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110331_001-1-scaled.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110331_001-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, both modems function very similar to previous modems, so with the drivers available in the Linux kernel, and standard &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;ppp&quot;&gt;pppd support in OpenEmbedded&lt;&#x2F;a&gt;, they worked fine.&lt;&#x2F;p&gt;
&lt;p&gt;The Verizon UML290 modem provides a challenge in that it must be manually switched between 4G and 3G modes.  Typically this is done automatically by the vzaccess program Verizon supplies with the modem that runs on Windows.  The solution for this system was to manually set the modem to 3G mode as detailed on the following page:&lt;&#x2F;p&gt;
&lt;p&gt;﻿&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.evdoinfo.com&#x2F;content&#x2F;view&#x2F;3492&#x2F;64&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.evdoinfo.com&#x2F;content&#x2F;view&#x2F;3492&#x2F;64&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It appears that some embedded systems such as the Cradlepoint routers have implemented automatic 3G&#x2F;4G switching support for the UML290, so this is no doubt possible with a little effort.&lt;&#x2F;p&gt;
&lt;p&gt;The Sprint U600 modem appears to default to 3G, or automatically switch inside the modem.&lt;&#x2F;p&gt;
&lt;p&gt;The same pppd scripts can be used with both modems:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_um290
user a
password v
connect &amp;quot;&#x2F;usr&#x2F;sbin&#x2F;chat -v -f &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_um290_chat&amp;quot;
defaultroute
usepeerdns
ttyACM0
921600
local
usepeerdns
debug
-detach
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;# &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_um290_chat
&amp;#39;&amp;#39; &amp;#39;ATZ&amp;#39;
&amp;#39;OK&amp;#39; &amp;#39;ATDT#777&amp;#39;
&amp;#39;CONNECT&amp;#39; &amp;#39;&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To initiate a connection:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;pppd call verizon_um290
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With Verizon cellular modems, it appears that port 22 is often blocked, so if you need to access a remote device via ssh, you may need to run ssh on a higher port number.  With 4G networks, it appears that the networking setup may be different in that a public IP address may not be assigned.  From the above evdoinfo.com page, we find the following text:&lt;&#x2F;p&gt;
&lt;p&gt;﻿﻿&lt;em&gt;This fix will also work for users looking to use their device for remote based applications because it assigns a public facing IP address (3G ONLY). With eHRPD you’re assigned a private IP in either 3G or 4G mode, which has prevents UML290 users from accessing remote applications.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps the Rev A HDR Service mode will also work in 4G mode, but its seems as cellular networks become more complicated, there will be more issues to deal with in using USB Cellular modems for remote access in embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Past articles on USB Cellular modems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;353&#x2F;sprint-598u-usb-broadband-modem-in-embedded-systems&#x2F;&quot;&gt;&#x2F;353&#x2F;sprint-598u-usb-broadband-modem-in-embedded-systems&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;203&#x2F;using-a-verizon-usb720-modem-in-an-embedded-linux-system&#x2F;&quot;&gt;&#x2F;203&#x2F;using-a-verizon-usb720-modem-in-an-embedded-linux-system&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git and Distributed Development</title>
        <published>2011-03-29T00:00:00+00:00</published>
        <updated>2011-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/832/git-and-distributed-development/"/>
        <id>https://bec-systems.com/832/git-and-distributed-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/832/git-and-distributed-development/">&lt;p&gt;This is part of an ongoing &lt;a href=&quot;..&#x2F;tag&#x2F;git&quot;&gt;series of articles&lt;&#x2F;a&gt; on the Git version control system.&lt;&#x2F;p&gt;
&lt;p&gt;The “&lt;a href=&quot;&#x2F;780&#x2F;git-and-multiple-repositories&#x2F;&quot;&gt;many repository&lt;&#x2F;a&gt;” paradigm has been partly driven by the  distributed development paradigm.  Git solves the problem of multiple  developers working in multiple repositories very well.  Because we want  to use and customize projects like the Linux kernel, U-boot, and  OpenEmbedded in our projects, then we naturally find ourself in the  situation where we need to manage multiple repositories.  Yes, you can  check the Linux kernel into your company Subversion repository, but you  are much better off long term if you bite the bullet and implement your  own Git infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;As we consider the product development process, we need to consider  the life cycle of a product.  Most products live for at least several  years, and will go through several software iterations.  If we can  update the software components we use, then we can add value to the  product in the form of new or updated drivers to support new  peripherals, new libraries, performance improvements, etc.  But, we are  dealing with millions of lines of source code, so we must have an  efficient way to deal with software projects of this size.  The below  Figure 2 illustrates how you might organize a typical project.  Notice  we can pull updates from the U-boot and Kernel source trees at any time  in the development process, and merge the changes with our own modifications.  We might have an outside team working an  application, and we then easily synchronize the repositories when it  makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;git-distributed_600-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;git-distributed_600-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many other design flows possible.  Once you have the  ability to support multiple branches and repositories easily, it becomes  trivial to implement a staging&#x2F;testing repository for a QA processes,  maintenance repositories for supporting old releases, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Even at a personal developer level, Git’s distributed capabilities offers many advantages.  Each Git workspace is actually a full Git repository.  This means you can check changes in locally, re-organize your changes, be able to track changes when off-line, etc.  For this reason, many developers are now using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;software&#x2F;scm&#x2F;git&#x2F;docs&#x2F;git-svn.html&quot;&gt;git-svn&lt;&#x2F;a&gt; when they need to work with Subversion repositories.  With git-svn, you have all the benefits of using git locally, and yet you can easily synchronize with Subversion repositories.  And this leads us to our next topic: cheap branches (coming soon).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How do modern USB chargers work</title>
        <published>2011-03-19T00:00:00+00:00</published>
        <updated>2011-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/800/how-do-modern-usb-chargers-work/"/>
        <id>https://bec-systems.com/800/how-do-modern-usb-chargers-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/800/how-do-modern-usb-chargers-work/">&lt;p&gt;As we help customers design products, we often try to leverage the latest cell phone practices and technologies.  One of these is USB charging.  There has been a push in recent years to standardize on USB chargers for cell-phones.  There are a number of organizations involved including the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.usb.org&quot;&gt;USB-IF&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.omtp.org&#x2F;&quot;&gt;OMTP&lt;&#x2F;a&gt;.  Two of the specification available include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;﻿﻿﻿[http:&#x2F;&#x2F;internal.omtp.org&#x2F;Lists&#x2F;ReqPublications&#x2F;Attachments&#x2F;59&#x2F;OMTP CCLDC V1.1 Final.pdf](http:&#x2F;&#x2F;internal.omtp.org&#x2F;Lists&#x2F;ReqPublications&#x2F;Attachments&#x2F;59&#x2F;OMTP CCLDC V1.1 Final.pdf)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.usb.org&#x2F;developers&#x2F;devclass_docs&#x2F;Battery_Charging_V1_2.zip&quot;&gt;http:&#x2F;&#x2F;www.usb.org&#x2F;developers&#x2F;devclass_docs&#x2F;Battery_Charging_V1_2.zip&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is also a Chinese standard titled the “Telecommunications Industry Standard of the PRC“ that has been instrumental in influencing these standards.&lt;&#x2F;p&gt;
&lt;p&gt;The fundamental problem is a battery powered device needs to know if it is plugged into a computer USB port, or a dedicated charger.  A standard USB port on a computer is only specified to provide 500mA.  Typically a dedicated charger that plugs into a wall outlet provides more current than 500mA so that the battery can be charged quicker.  To differentiate between a computer USB port, and a dedicated charger, the dedicated charger shorts the D+ and D- USB signals together with a resistance of less than 200 ohms (specified by USB-IF).&lt;&#x2F;p&gt;
&lt;p&gt;One of the goals of these standards is that any charger can be used with any battery powered device.  The next question is how do we handle the case where every USB charger has a different rated current?  How can a device that charges its battery at 1.7A be compatible with a charger that only outputs 0.7A?  One theoretical solution would be for the device to query the current capacity of the charger and then only use that much current.  It turns out a much simpler approach is used.  The USB-IF provides the following chart in the above specification:&lt;&#x2F;p&gt;
&lt;figure&gt;&lt;a rel=&quot;attachment wp-att-801&quot; href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;Selection_009-1.png&quot;&gt;&lt;figcaption&gt;&lt;img title=&quot;USB-IF charger operating range&quot; src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;Selection_009-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;a&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;As long as the charger outputs power in the Required Operating Range, the battery powered device must be able to use whatever power is available to charge its battery.  If the device uses more current than the charger can supply, the charger simply goes into a constant current mode and the battery charges slower than it would with a higher capacity charger.  Thus we have a very simple scheme where we can theoretically use any charger with any device.&lt;&#x2F;p&gt;
&lt;p&gt;As a simple test, I charged a Nokia N900 phone (which came with a  1.2A charger) with a smaller LG charger that is rated for 0.7A.  I  monitored the LG charger a couple times during charging to make sure it  was not getting hot.  It seemed to charge the N900 battery just fine.&lt;&#x2F;p&gt;
&lt;p&gt;When  purchasing after-market USB chargers, it is sometimes difficult to  determine if they have the USB D+ and D- lines shorted together.  In  once case I purchased a car USB charger that did not work with my  phones, but was able to “fix” it by disassembling it, and putting a  solder blob between the D+ and D- signals on the USB connector.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_001-1.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_001-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_002-1.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_002-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_003-1.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_003-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While shorting the D+ and D- pins usually makes a charger work, it is nice to know if the charger is compliant with the USB-IF specification and is designed to work in the constant current mode without shutting down, catching fire, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git Overview Screencast</title>
        <published>2011-03-17T00:00:00+00:00</published>
        <updated>2011-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/778/git-overview-screencast/"/>
        <id>https://bec-systems.com/778/git-overview-screencast/</id>
        
        <content type="html" xml:base="https://bec-systems.com/778/git-overview-screencast/">&lt;p&gt;This &lt;a href=&quot;..&#x2F;..&#x2F;video&#x2F;2010-08-26_git.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; (use Firefox to view the screencast) provides an overview of the  Git version control system.  There are 3 features of Git that are  especially interesting:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;many repositories (vs. one large repository)&lt;&#x2F;li&gt;
&lt;li&gt;distributed development&lt;&#x2F;li&gt;
&lt;li&gt;cheap branches&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The fundamental driver for better tools is increasing system  complexity.  More and more we are required to manage and integrate more  third party software, work in distributed teams, and more effectively  re-use the software we do have.  Git is a tool that helps you accomplish  these goals.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git and Why Multiple Repositories</title>
        <published>2011-03-17T00:00:00+00:00</published>
        <updated>2011-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/780/git-and-multiple-repositories/"/>
        <id>https://bec-systems.com/780/git-and-multiple-repositories/</id>
        
        <content type="html" xml:base="https://bec-systems.com/780/git-and-multiple-repositories/">&lt;p&gt;This is part of an ongoing &lt;a href=&quot;&#x2F;tags&#x2F;git&#x2F;&quot;&gt;series of articles&lt;&#x2F;a&gt; on the Git version control system.&lt;&#x2F;p&gt;
&lt;p&gt;This article discusses the trend in software configuration management toward multiple repositories, rather than one large repository.  In the past when many companies used Subversion or comparable systems, there was typically one huge  company repository (I’ve seen them in the 10’s of GB in size) that held a  hierarchical tree of all the company source code.  This worked fairly  well, and is comfortable in that the organization is very similar to a file system  directory structure.  However, this model is not very flexible in that  it does not have a consistent way to re-use components between different  projects.  Some people simply copy source code.  Some have a “common”  project that is included in all their other projects.  Subversion  externals can be used.  With Git, typically a separate repository is  created for each software component.  There are perhaps several reasons  for this, but one reason is that Git simply does not scale to huge  multi-GByte repositories.  However, this turns out to be a blessing in  disguise as I think it is a better model in many cases.  What we end up  with is more of a catalog of software components rather than a rigid hierarchy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;svn-vs-git_600-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;svn-vs-git_600-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There  is much emphasis these days on modular, re-usable software  components (Object Oriented Programming, plugins, etc.).  Why not keep  things modular at the repository level?  Another example of this type of  organization is the Internet itself.  It is not a hierarchy of  information, but rather a flat system that is organized by hyperlinks.&lt;&#x2F;p&gt;
&lt;p&gt;One  of the benefits of organizing your source code this way is that it  encourages clean boundaries between software components.  Each software  component needs to stand on its own without being propped up  by header files located in an unrelated source tree 3 levels up in the directory hierarchy.  This type of organization forces us to make better use of standard build system practices.&lt;&#x2F;p&gt;
&lt;p&gt;How do you implement this type of repository infrastructure?  Build systems such as OpenEmbedded, Gentoo, and the Android build system manage this fairly well.  However, Git also includes a feature named “submodules” that provides a mechanism for one repository to reference source code from another.  What you end up using really depends on your needs, and what you are trying to accomplish.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a href=&quot;&#x2F;778&#x2F;git-overview-screencast&#x2F;&quot;&gt;screencast&lt;&#x2F;a&gt; is also available that covers this topic.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>C++ callbacks to member functions</title>
        <published>2010-12-16T00:00:00+00:00</published>
        <updated>2010-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/760/c-callbacks-to-member-functions/"/>
        <id>https://bec-systems.com/760/c-callbacks-to-member-functions/</id>
        
        <content type="html" xml:base="https://bec-systems.com/760/c-callbacks-to-member-functions/">&lt;p&gt;How to properly do callbacks to C++ member functions is something that has intrigued me for some time now.  There are a number of solutions, none of which I really liked.  But now with the &lt;strong&gt;std::tr1::function&lt;&#x2F;strong&gt; and &lt;strong&gt;std::tr1::bind&lt;&#x2F;strong&gt; functions, there appears to be a clean solution.&lt;&#x2F;p&gt;
&lt;p&gt;In the past, if you wanted a callback to a C++ member function a typical approach was to create a static function wrapper as described &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.parashift.com&#x2F;c++-faq-lite&#x2F;pointers-to-members.html&quot;&gt;here&lt;&#x2F;a&gt;.  However, this is ugly, and a step backwards from the capabilities of plain old C.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;std::tr1::function&lt;&#x2F;strong&gt; is a function wrapper that can be used to create function objects for a number of scenarios.  We are interested in representing class member functions.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;tr1&#x2F;functional&amp;gt;

struct X {
	int foo(int);
};

std::tr1::function&amp;lt;int (X*, int)&amp;gt; f;

f = &amp;amp;X::foo;

X x;
f(&amp;amp;x, 6);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;f() is now a simple function representation that can be passed around, etc.  However, what we don’t like is the reference to the struct X type, which makes it much less generic.  This is where the &lt;strong&gt;std::tr1::bind&lt;&#x2F;strong&gt; function comes in.  With bind, we can dynamically bind one function to another, and re-arrange the arguments, etc.  So to make a generic portable function that points to X::foo(), we can do something like the following.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;tr1&#x2F;functional&amp;gt;

struct X {
	int foo(int);
};

std::tr1::function&amp;lt;int (int)&amp;gt; f;

X x;
f = std::tr1::bind(&amp;amp;X::foo, &amp;amp;x, _1);

f(6);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, f() is a very generic function that could be used in various interfaces without specifically referencing struct X.&lt;&#x2F;p&gt;
&lt;p&gt;A more complete example of how callbacks might work is given below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;tr1&#x2F;functional&amp;gt;

struct B
{
  std::tr1::function &amp;lt;void ()&amp;gt; _callback;

void reg_callback(std::tr1::function &amp;lt;void ()&amp;gt; callback)
  {
    _callback = callback;
  }

void unreg_callback()
  {
    _callback = NULL;
  }

void process() {
    &#x2F;&#x2F; simply calls callback
    if (_callback)
      _callback();
  }
};

struct A
{
  B * _b;

A(B * b) :
    _b(b)
  {
    std::tr1::function&amp;lt;void()&amp;gt; callback;
    callback = std::tr1::bind(&amp;amp;A::callback, this);
    b-&amp;gt;reg_callback(callback);
  }

~A()
  {
    _b-&amp;gt;unreg_callback();
  }

void callback() {
    std::cout &amp;lt;&amp;lt; &amp;quot;A::callback called\n&amp;quot;;
  }

void process() {
    _b-&amp;gt;process();
  }
};

int main()
{
  B * b = new B();
  A * a = new A(b);

&#x2F;&#x2F; the following is example where object b calls
  &#x2F;&#x2F; back into a method
  &#x2F;&#x2F; in object a
  a-&amp;gt;process();

&#x2F;&#x2F; now delete object a, and verify the callback
  &#x2F;&#x2F; in B does not crash or still get called
  delete a;

&#x2F;&#x2F; now b should not execute the callback
  b-&amp;gt;process();
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the above example, the callback in the object &lt;em&gt;a&lt;&#x2F;em&gt; will be called once.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Yocto and OpenEmbedded</title>
        <published>2010-12-10T00:00:00+00:00</published>
        <updated>2010-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/755/yocto-and-openembedded/"/>
        <id>https://bec-systems.com/755/yocto-and-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/755/yocto-and-openembedded/">&lt;p&gt;Recently, I attended an Embedded Linux summit hosted by the Linux Foundation to discuss the Yocto project.  Overall, I thought the meeting was very positive and constructive. Having met and discussed at length the methods and goals of the Linux Foundation with some of their people, I’m impressed with their approach. They are there to help Linux succeed in the Embedded space in any way they can.&lt;&#x2F;p&gt;
&lt;p&gt;It is my understanding that the Yocto project has the goal of making Linux much more accessible and usable in embedded systems, and improve efficiencies. While the OpenEmbedded project has served many of us well for many years, we all can readily understand there are some deficiencies. These can be overcome by experienced developers, but there are a number of areas that can obviously be improved. Not only are we concerned with making it easier for new users to use Embedded Linux, I think there are areas where we can drastically improve the efficiency of implementing embedded Linux systems for those who are experienced. It was stated once that tools implemented must be useful to both the new developer as well as the experienced developer.&lt;&#x2F;p&gt;
&lt;p&gt;It should be noted that building an embedded Linux system is an inherently complex undertaking, and although we can improve tools and processes to make it more efficient, and somewhat easier, in the end it is still a very complex problem, and will require considerable skill to be an effective embedded Linux developer. There is no substitute for experience, and developer skill. Just as we would not slap a fancy GUI on top of a robotic surgery instrument, and tell a novice to have at it, likewise it is still going to require considerable engineering skill to be effective in developing Embedded Linux systems. But, if we improve the base technologies, and tools, we will spend less time messing with these and doing the same things over and over, and will have more resources toward implementing new things.&lt;&#x2F;p&gt;
&lt;p&gt;One example of the pain experienced in a typical OpenEmbedded system is getting Oprofile to run. Oprofile requires that ARM system be built with frame pointers (OE defaults to not), and that you have symbols in your binaries. Figuring out how to build a reasonably sized image with the needed symbols might be a 1-2 day process for me. Then there is the issue of kernel symbols, etc. I’m sure many other developers go through the same steps, but as many of us are paid to develop products on tight schedules, we don’t have the time to polish the Oprofile integration and tools.&lt;&#x2F;p&gt;
&lt;p&gt;As an extension of this, the application development story with OpenEmbedded is not all that great. Yes, we can generate a binary SDK, but again it may take a couple days of messing around to figure out the process, and get all the necessary libraries, etc. Then you still have the problem that application developers want Eclipse&#x2F;Qt Creator integration, etc. Again, this can all be done, but takes time, and many people are doing the same things over and over again.&lt;&#x2F;p&gt;
&lt;p&gt;The Yocto project seems to have two primary thrusts:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;stabilize a subset of the OpenEmbedded (called Poky) metadata and make it very high quality.&lt;&#x2F;li&gt;
&lt;li&gt;improve tools associated with the build process, and general embedded Linux development.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;One thing the OpenEmbedded project has historically lacked in the past is industry funding and ongoing developer commitment. The OE project is characterized by a rotating group of developers. When someone needs OE for a project, they jump in and do a lot of work on OE, then they disappear again once their need is met. We have very few developers who work on the project consistently for long periods of time. This has been positive in some ways in that we have a very large number of contributors, and a very open commit policy. There are so many patches coming in right now, we can’t even keep up with processing them. Week after week, we have a healthy number of committers and changesets. The community behind OE is rather astounding, and it is amazing how OE succeeds almost in spite of itself as a self organizing project without much organization.&lt;&#x2F;p&gt;
&lt;p&gt;In the past the OpenEmbedded and Poky projects have existed as two independent trees, and things were shared back and forth manually. This works fairly well as recipes are self contained, and generally can simply be copied from one tree to another. However, some of the core recipes are fairly complex, and if they start to diverge, then sharing information can get more difficult.&lt;&#x2F;p&gt;
&lt;p&gt;It seems the vision that is emerging is that Poky could become the core component of OpenEmbedded. Poky would contain a very controlled subset of core recipes that must remain at a very high quality level. OpenEmbedded could then expand on this (through the use of layers) to provide the breadth and scope it has traditionally provided.&lt;&#x2F;p&gt;
&lt;p&gt;We may bemoan the lack of quality in the OpenEmbedded project as it has 1000’s of recipes, and many of them have rotted, etc. But as a consultant helping people implement products, I still find considerable value in this. For example, one of the products I support uses the HPLIP drivers from HP. Yes, the recipe is broke every time I go to use the latest version, but with a little work I can get it working again. Having something to start with provides value. The same is true for the geos mapping libraries. Very few people are going to use geos, so it will never be in a Poky type repository, but some of us do use geos, so having a common place like OpenEmbedded to put recipes like this is very important. Using Poky as the core of OpenEmbedded seems like a win-win. We are relieved of some of the burden of maintaining core components (like compilers, C library, tool integration, sdk generation, etc), but we can still have a very open culture, and provide a wide scope of platform, library, and application support that we have historically provided.&lt;&#x2F;p&gt;
&lt;p&gt;Richard Purdie is poised to become the Linus Torvalds of Yocto, and if OpenEmbedded choses to base on Poky, then the Torvalds of the OpenEmbedded core. I am personally fine with this as I don’t know anyone else who has contributed so much time and has the same level of skill in the OE&#x2F;Poky area. He has proven over time to be levelheaded and able to deal with difficult situations. Also, as a Linux Foundation fellow, he is positioned to be company neutral, which is very important for someone in this position.&lt;&#x2F;p&gt;
&lt;p&gt;Yocto is using a “pull” model similar to the Linux kernel for accepting changes. It is planned to put maintainers in place for various subsystems. With the goal of providing a very high quality subset of embedded Linux technologies, it seems this makes a lot of sense. If OpenEmbedded choses to base on Poky, there is no reason OpenEmbedded can’t continue to still use the push model for its layer that has worked well in the past. But, as we see patches languishing in the patchwork, perhaps a pull model might actually be more efficient at processing incoming patches so they don’t get lost. This is also an area where layers might actually help in that we have dedicated people committed to processing patches for each layer. One of the problems with the OpenEmbedded project with its 1000’s of recipes, the structure is very flat, and its fairly difficult to divide it up into areas of responsibility.&lt;&#x2F;p&gt;
&lt;p&gt;So going forward, it seems that if OpenEmbedded can somehow use Poky as a core technology (just like it uses bitbake, etc), then we could have the best of both worlds. With Poky, we get strong industry commitment and dedicated people working on making the core pieces better, and the tools better (50 engineers are already dedicated). This is something those of us developing products don’t really have time for and we are not currently funded to do this. With OpenEmbedded we can still keep our broad involvement, and vast recipe and target collection. Yes, the quality of OpenEmbedded will be lower, but it still provides a different type of value. Poky provides the known stable core, and OpenEmbedded is just that–it is “open”, and provides the broad menu of components that can be used. Over time this could evolve into something different, but for now it seems a good place to start.&lt;&#x2F;p&gt;
&lt;p&gt;The last thing to consider is the OpenEmbedded brand. It is recognizable from the name what it is (unlike Yocto, and Poky). It has had broad exposure for many years. It has historically been very vendor neutral with very little corporate direction or influence. From this perspective, it seems the Yocto project can benefit greatly from having an association with the OpenEmbedded project.  This topic was discussed at the summit, and there was general consensus on the strong awareness of the OpenEmbedded brand, as well as an openness to how branding for the Yocto core build system might look.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Qt Developer needed</title>
        <published>2010-11-05T00:00:00+00:00</published>
        <updated>2010-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/747/qt-developer-needed/"/>
        <id>https://bec-systems.com/747/qt-developer-needed/</id>
        
        <content type="html" xml:base="https://bec-systems.com/747/qt-developer-needed/">&lt;p&gt;We are currently in need of a Qt developer to help on a project.  If you are interested, please &lt;a href=&quot;&#x2F;#work-together&quot;&gt;contact us&lt;&#x2F;a&gt;.  Thanks.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded srctree and gitver</title>
        <published>2010-10-11T00:00:00+00:00</published>
        <updated>2010-10-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/711/openembedded-srctree-and-gitver/"/>
        <id>https://bec-systems.com/711/openembedded-srctree-and-gitver/</id>
        
        <content type="html" xml:base="https://bec-systems.com/711/openembedded-srctree-and-gitver/">&lt;p&gt;Recently an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&quot;&gt;OpenEmbedded&lt;&#x2F;a&gt; class name &lt;em&gt;srctree&lt;&#x2F;em&gt; became usable.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;classes&#x2F;srctree.bbclass&quot;&gt;srctree.bbclass&lt;&#x2F;a&gt; enables operation inside of an existing source tree for a project, rather than using the fetch&#x2F;unpack&#x2F;patch idiom.  The srctree.bbclass in combination with the OpenEmbedded &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;classes&#x2F;gitver.bbclass&quot;&gt;gitver.bbclass&lt;&#x2F;a&gt; and git submodules provides a very interesting way to build custom software with OpenEmbedded.&lt;&#x2F;p&gt;
&lt;p&gt;One of the classic problems with OpenEmbedded is how do application and kernel developers use it.  While OpenEmbedded excels at automating image builds, it is less friendly when used as a a cross development tool.  Historically there are several options for iterative development:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;develop in the working directory: cd &lt;tmp&gt;&#x2F;work&#x2F;arm…&#x2F;&lt;my recipe&gt;; ..&#x2F;temp&#x2F;run.do_compile …&lt;&#x2F;li&gt;
&lt;li&gt;a variation of #1: bitbake -c devshell &lt;my recipe&gt;&lt;&#x2F;li&gt;
&lt;li&gt;manually set up an environment that uses the toolchain generated by OE.  As example see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&#x2F;blob&#x2F;master&#x2F;envsetup.sh&quot;&gt;this script&lt;&#x2F;a&gt; in the &lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;BEC OE template&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;a variation of #3: export a SDK that includes a toolchain and libs&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;While the above solutions work OK, the process can be a little cumbersome.  Unless your OE recipe pulls software directly from the TIP of a SVN repository, you may have to manually update the recipe after you make changes, create patch files, etc.  There is also the problem that if your recipe fetches the latest from SVN, it drastically slows down the recipe parsing as it has to check the repository for a new version every time the recipe is processed.&lt;&#x2F;p&gt;
&lt;p&gt;The optimal solution would to be to simply check a software component out of a version control system, and build it directly using OpenEmbedded.  Icing on the cake would be if the package generated would automatically extract version information from the version control system.  This would facilitate iterative development for software components that need to be cross compiled.&lt;&#x2F;p&gt;
&lt;p&gt;Although srctree can be used with any directory of source code, it really works best with a git repository.  The gitver.bbclass provides a GITVER variable which is a (fairly) sane version, for use in ${PV}, extracted from the ${S} git checkout, assuming it is one (text from recipe).  gitver uses the ‘git describe’ command to extract the last tag and uses that for the version.&lt;&#x2F;p&gt;
&lt;p&gt;The best way to illustrate the use of these tools is an example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The easiest way to try this is clone the above project in your openembedded&#x2F;recipes directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ cd openembedded&#x2F;recipes
$ git clone https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo.git
$ cd autotools-demo
$ git describe
1.1
$ git tag -l
1.0
1.1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that &lt;em&gt;git describe&lt;&#x2F;em&gt; simple returns the latest tag.   The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo&#x2F;blob&#x2F;master&#x2F;autotools-demo.bb&quot;&gt;recipe&lt;&#x2F;a&gt; can be located in the same directory as the source code and has the following contents:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# recipe to build the autotools-demo in the working tree

inherit srctree autotools gitver

PV = &amp;quot;${GITVER}&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Can’t get much easier than that!  If you build the recipe, you end up with a package:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ bitbake autotools-demo
$ ls tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;armv5te&#x2F;autotools-demo_1.1-r0.6_armv5te.ipk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, what happens if you make changes and commit them?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ cd ...&#x2F;autotools-demo
$ (make a change and commit)
$ git describe
1.1-1-gfbc1ecc (notice the count and hash automatically appended)
$ (make another change and commit)
$ git describe
1.1-2-g7ad3715 (notice the count is now 2)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we bitbake the recipe now, we end up with a packaged named:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;armv5te&#x2F;autotools-demo_1.1-2-g7ad3715-r0.6_armv5te.ipk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;gitver&lt;&#x2F;em&gt; class in OpenEmbedded automatically takes care of creating a usable PV (package version) that always increments.&lt;&#x2F;p&gt;
&lt;p&gt;So in summary, &lt;em&gt;srctree&lt;&#x2F;em&gt; and &lt;em&gt;gitver&lt;&#x2F;em&gt; give developers a convenient way to handle custom components that change often in an Embedded Linux build without increasing parse times, requiring manual tweaks to version numbers, or creating a separate workspace for each version of the application that is built.  As practices such as continuous integration become more common, OpenEmbedded features like this are increasingly needed.  An added benefit is that the OpenEmbedded recipe can now be stored in the same location as the source code.  Perhaps in the future, most applications will include an OpenEmbedded recipe as part of their source code and git submodules could be used to simple populate the components you want to use.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;2017-11-08 update: A tool named &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;2.4&#x2F;mega-manual&#x2F;mega-manual.html#using-devtool-in-your-sdk-workflow&quot;&gt;devtool&lt;&#x2F;a&gt; is now the preferred way to do much of the above.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Qt Creator for C&#x2F;C++ development</title>
        <published>2010-08-07T00:00:00+00:00</published>
        <updated>2010-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/704/qt-creator-for-cc-development/"/>
        <id>https://bec-systems.com/704/qt-creator-for-cc-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/704/qt-creator-for-cc-development/">&lt;p&gt;Recently, I’ve been evaluating &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;qt.nokia.com&#x2F;developer&#x2F;qt-qtcreator-prerelease&quot;&gt;Qt Creator&lt;&#x2F;a&gt; for general C&#x2F;C++ development.  I’m currently involved in the development of a rather large C++ application that is approaching 200,000 lines of code and 1000 source modules.  In the past, I’ve typically used Vim for editing, and Eclipse as a gdb front-end when needed.  Qt Creator is a rather new tool developed by Nokia’s Qt team.  What initially attracted my attention was that one of the reasons the project was started was no existing tools effectively handled the Qt codebase, which is quite large.  Things I like about Qt Creator:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;it works fairly well with any C++ Make based project.  This includes projects built with autotools as well as the Qt Qmake build system.&lt;&#x2F;li&gt;
&lt;li&gt;easy to import existing projects&lt;&#x2F;li&gt;
&lt;li&gt;it is very fast.  Indexing 200,000 lines of code happens in around a minute or so.&lt;&#x2F;li&gt;
&lt;li&gt;Provides a Vim compatibility mode that actually works&lt;&#x2F;li&gt;
&lt;li&gt;provides fast methods for finding files, symbols, and seeing where symbols are used&lt;&#x2F;li&gt;
&lt;li&gt;did I mention yet it is &lt;em&gt;&lt;strong&gt;fast&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I also &lt;a href=&quot;&#x2F;video&#x2F;2010-08-07_qt-creator-demo.ogv&quot;&gt;recorded a screencast that demos Qt Creator with a large project&lt;&#x2F;a&gt; (can be viewed in firefox).  As always, I’m interested in what others find interesting in this or other tools.  Future efforts will be to use Qt Creator to build and remotely debug ARM binaries – I am interested in what others have done in this regard.&lt;&#x2F;p&gt;
&lt;p&gt;If you do try Qt Creator, I recommend the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;qt.nokia.com&#x2F;developer&#x2F;qt-qtcreator-prerelease&quot;&gt;latest pre-release snapshot&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded Linux Presentation in Cleveland</title>
        <published>2010-07-26T00:00:00+00:00</published>
        <updated>2010-07-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/701/embedded-linux-presentation-in-cleveland/"/>
        <id>https://bec-systems.com/701/embedded-linux-presentation-in-cleveland/</id>
        
        <content type="html" xml:base="https://bec-systems.com/701/embedded-linux-presentation-in-cleveland/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;coledd.com&#x2F;&quot;&gt;Chris Cole&lt;&#x2F;a&gt; and I will be &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.clevelandieee.org&#x2F;content&#x2F;embedded-linux-development&quot;&gt;giving a presentation&lt;&#x2F;a&gt; in Cleveland Tues evening (2010-07-26).  Stop by if you are interested.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git submodules: what to do when you commit to (no branch)</title>
        <published>2010-06-17T00:00:00+00:00</published>
        <updated>2010-06-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/696/git-submodules-what-to-do-when-you-commit-to-no-branch/"/>
        <id>https://bec-systems.com/696/git-submodules-what-to-do-when-you-commit-to-no-branch/</id>
        
        <content type="html" xml:base="https://bec-systems.com/696/git-submodules-what-to-do-when-you-commit-to-no-branch/">&lt;p&gt;When using git submodules, eventually you’ll run into a situation where a workspace has checked out a submodule as (no branch), and you unknownly make modifications and commits to (no branch).  Now what?  It turns out Git has a very useful feature named reflog.  Reflog keeps a local time based log of all activity.  That means that as long as you do not garbage collect your workspace, you can go back to any point in time and get any commit that was made.  This is useful in a number of scenarios, but lets consider the case where we made two commits to a submodule in the (no branch) state.  We are then ready to push our changes to the upstream repo and we get:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git push bec HEAD
error: unable to push to unqualified destination: HEAD
The destination refspec neither matches an existing ref on the remote nor
begins with refs&#x2F;, and we are unable to guess a prefix based on the source ref.
error: failed to push some refs to &amp;#39;git@git.bec-systems.com:openembedded.custom&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we do a git log, we find we are on the infamous (no branch).&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git branch
* (no branch)
  master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point we may wonder what to do.  How do we get these changes onto the master branch?  Using git reflog, we can view all commits and changes to our local repository based on time.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git reflog
6d195b3 HEAD@{0}: commit: add recipe for qt-embedded image
4cf1bd6 HEAD@{1}: commit: add touchscreen utilities
bcc673c HEAD@{2}: checkout: moving from master to bcc673c9824e916a7ec6c04f60a17116af539423
56d9def HEAD@{3}: commit: add more features
5286f87 HEAD@{4}: commit: rename debug image
90896de HEAD@{5}: pull : Fast-forward
5cc3f3b HEAD@{6}: checkout: moving from 90896deb2a25f0d40b1e6305a0ad994f932f22d8 to master
90896de HEAD@{7}: checkout: moving from master to 90896deb2a25f0d40b1e6305a0ad994f932f22d8
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Git will keep our keeps commits to (no branch) even though we might switch to another name branch.  And using git reflog, we can easily find these commits and merge them to the master branch.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git checkout master
Previous HEAD position was 6d195b3... add recipe for qt-embedded image
Switched to branch &amp;#39;master&amp;#39;
Your branch is behind &amp;#39;origin&#x2F;master&amp;#39; by 1 commit, and can be fast-forwarded.
cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git reflog
56d9def HEAD@{0}: checkout: moving from 6d195b3909553b04cba3d3ac182076a2c6b866b2 to master
6d195b3 HEAD@{1}: commit: add recipe for qt-embedded image
4cf1bd6 HEAD@{2}: commit: add touchscreen utilities
bcc673c HEAD@{3}: checkout: moving from master to bcc673c9824e916a7ec6c04f60a17116af539423
56d9def HEAD@{4}: commit: add more features
5286f87 HEAD@{5}: commit: rename debug image
90896de HEAD@{6}: pull : Fast-forward
5cc3f3b HEAD@{7}: checkout: moving from 90896deb2a25f0d40b1e6305a0ad994f932f22d8 to master
90896de HEAD@{8}: checkout: moving from master to 90896deb2a25f0d40b1e6305a0ad994f932f22d8
cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git merge 6d195b3
Updating 56d9def..6d195b3
Fast-forward
 recipes&#x2F;images&#x2F;bec-debug-image.bb       |   38 +++++++++++++++++++-----------
 recipes&#x2F;images&#x2F;bec-qt-embedded-image.bb |    8 ++++++
 2 files changed, 32 insertions(+), 14 deletions(-)
 create mode 100644 recipes&#x2F;images&#x2F;bec-qt-embedded-image.bb
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, the changes have been merged to the master branch, and we can now push to our public repository:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git push bec HEAD
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (9&#x2F;9), done.
Writing objects: 100% (10&#x2F;10), 1.13 KiB, done.
Total 10 (delta 3), reused 0 (delta 0)
To git@git.bec-systems.com:openembedded.custom
   bcc673c..6d195b3  HEAD -&amp;gt; master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Git reflog can also be used to restore commits that you decided at one point to throw away with “git reset --hard HEAD~2”, etc.  As long as you don’t garbage collect the repo, they are simply dangling state and always still exist.  This is just another example of the ways git can be very confusing, but also very powerful if you understand how it works.&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;a href=&quot;&#x2F;video&#x2F;2010-06-17_git-reflog.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; covers the operations in this article.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Installing OMAP3 images on a SD card</title>
        <published>2010-06-14T00:00:00+00:00</published>
        <updated>2010-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/687/installing-omap3-images-on-a-sd-card/"/>
        <id>https://bec-systems.com/687/installing-omap3-images-on-a-sd-card/</id>
        
        <content type="html" xml:base="https://bec-systems.com/687/installing-omap3-images-on-a-sd-card/">&lt;p&gt;This article and screen-cast is a continuation of that last couple posts describing the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.bec-systems.com&#x2F;cgit.cgi&#x2F;oe-build&#x2F;&quot;&gt;BEC OE build template&lt;&#x2F;a&gt;.  The purpose again for a build system is to automate tedious manual tasks, and in doing so, we end up documenting how the build system works.  Having a good build system is important during product development so that you have an easy, repeatable process for building and deploying images.  One of these tasks is setting up a SD card and installing images to the SD card that an OMAP system can boot from.  This &lt;a href=&quot;&#x2F;video&#x2F;2010-06-14_installing-on-omap.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; goes over the script and makefile targets that are used to automate this process.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, the steps to set up a SD card and install an image using the build template are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;cd &lt;build template directory&gt;&lt;&#x2F;li&gt;
&lt;li&gt;determine the SD card device name (&#x2F;dev&#x2F;sdX)&lt;&#x2F;li&gt;
&lt;li&gt;unmount any file systems mounted on the SD card&lt;&#x2F;li&gt;
&lt;li&gt;sudo .&#x2F;scripts&#x2F;omap-sd-partitions.sh &#x2F;dev&#x2F;sdX  (make sure you have the right device!!!)&lt;&#x2F;li&gt;
&lt;li&gt;make omap-install-boot&lt;&#x2F;li&gt;
&lt;li&gt;make omap-install-&lt;image name&gt;-rootfs&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Previous articles in this series:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;OpenEmbedded build template&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;..&#x2F;668&#x2F;creating-a-custom-openembedded-image&quot;&gt;Creating  a Custom OpenEmbedded Image&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Build Template posted</title>
        <published>2010-06-08T00:00:00+00:00</published>
        <updated>2010-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/666/openembedded-build-template-posted/"/>
        <id>https://bec-systems.com/666/openembedded-build-template-posted/</id>
        
        <content type="html" xml:base="https://bec-systems.com/666/openembedded-build-template-posted/">&lt;p&gt;A password protected version of this article accidently got pushed into the feed before it was finished, so this post is simply to indicate the following article is now available.  Sorry for the confusion.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;&#x2F;637&#x2F;oe-build-template&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creating a Custom OpenEmbedded Image</title>
        <published>2010-06-08T00:00:00+00:00</published>
        <updated>2010-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/668/creating-a-custom-openembedded-image/"/>
        <id>https://bec-systems.com/668/creating-a-custom-openembedded-image/</id>
        
        <content type="html" xml:base="https://bec-systems.com/668/creating-a-custom-openembedded-image/">&lt;p&gt;In this article screencast, we’ll demonstrate how to create a custom Linux OS image using the OpenEmbedded build system.  This demonstration builds on the earlier &lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;article about using the BEC OE build template&lt;&#x2F;a&gt;.  The OpenEmbedded build system is similar to Linux distributions in that you can select from a wide array of components to install.  One of the big differences is you can select these components when building the OS image, instead of after you have installed the “standard” image.  This &lt;a href=&quot;&#x2F;video&#x2F;2010-06-07_bec-custom-oe-image.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; demonstrates how to set up a custom image (can be viewed with Firefox).&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a href=&quot;&#x2F;177&#x2F;the-correct-way-to-add-packages-to-an-openembedded-image&#x2F;&quot;&gt;related article&lt;&#x2F;a&gt; also covers this procedure.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, the steps include:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create an image recipe (typically in your meta data overlay).  An example is located &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.bec-systems.com&#x2F;cgit.cgi&#x2F;openembedded.custom&#x2F;tree&#x2F;recipes&#x2F;images&#x2F;bec-beagleboard-image.bb&quot;&gt;here&lt;&#x2F;a&gt;.  An existing image can be referenced for simplicity.&lt;&#x2F;li&gt;
&lt;li&gt;Figure out what packages need to be added.  This can be done by &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&quot;&gt;browsing the recipe tree&lt;&#x2F;a&gt; to see what is available.&lt;&#x2F;li&gt;
&lt;li&gt;Bitbake the recipe.&lt;&#x2F;li&gt;
&lt;li&gt;Look at what packages were generated.  In this example they are found in the &lt;em&gt;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;armv7a&lt;&#x2F;em&gt; directory.&lt;&#x2F;li&gt;
&lt;li&gt;Add the relevant package names to your image recipe.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As the OpenEmbedded project includes over 6000 recipes, it gives you a big head start in including standard components in your Embedded Linux build.  Leveraging these existing components is why we use Linux, and having a way to easily build and deploy these components to your target hardware is what OpenEmbedded is all about.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Build Template</title>
        <published>2010-06-05T00:00:00+00:00</published>
        <updated>2010-06-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/637/oe-build-template/"/>
        <id>https://bec-systems.com/637/oe-build-template/</id>
        
        <content type="html" xml:base="https://bec-systems.com/637/oe-build-template/">&lt;p&gt;Setting up an OpenEmbedded build is a fairly simple process if you carefully follow the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;Getting_started&quot;&gt;instructions&lt;&#x2F;a&gt;.  There are also a number of scripts available that automate the setup such as the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;OpenEmbedded_Tools_for_Eclipse_%28OTE%29&quot;&gt;OpenEmbedded Tools for Eclipse&lt;&#x2F;a&gt;, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.angstrom-distribution.org&#x2F;simplified-development-setup&quot;&gt;Angstrom setup scripts&lt;&#x2F;a&gt;, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;kom.kaeilos.com&#x2F;&quot;&gt;KaeilOS Openembedded Manager&lt;&#x2F;a&gt;, and I’m sure there are many more (feel free to add in comments section).  As we have helped a number of clients use OpenEmbedded in commercial projects, we have the following requirements for a build template:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The build needs to be completely automated such that only one step is required to build images.&lt;&#x2F;li&gt;
&lt;li&gt;We need to be able to lock down versions of various components.&lt;&#x2F;li&gt;
&lt;li&gt;Needs to be as simple as possible.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As we continue to think about creating a build template, the primary reason for creating one is to get repeatable builds with very little effort.  The build template serves as documentation; how did we build the 1.10 release.  A good build system allows any developer to create any release on about any machine at any time.  A good build system does not depend on the “golden build machine.”  We have been using makefile wrappers around OpenEmbedded for several years now to accomplish much of this.  These wrappers were typically stored in a Subversion repository with the rest of the project files.  However, now that most open source projects have moved to Git repositories, there are significant advantages to using Git for the build system.  Git has a feature called submodules which allows you to embed a git repository inside a source tree, always pointed at a particular commit.  In concept, this is perfect.  In practice, Git submodules are sometimes difficult to use, but considering the functionality provided, I think it is a reasonable trade-off.&lt;&#x2F;p&gt;
&lt;p&gt;The use of Git encourages a different development paradigm.  Typically when people use Subversion within a company, there is one repository that stores everything.  Subversion is actually quite good at this.  I’ve run into a number of companies who have repositories many GB in size that have been running for many years.  The stability is remarkable.  Git does not scale in this way, so people tend to set up a separate repository for each component, application, etc.  While there may be some disadvantages to this model, there are also significant advantages, and we can learn some of these by observing Open Source Software (OSS) development.  Just as we strive for modularity in software development where each class can stand on its own and be generally useful, OSS maintains this dynamic at the project level.  Each OSS project moves at its own pace, largely decoupled from other projects.  This dynamic forces a level of organization that might be neglected otherwise.  Likewise, in any project, if each major component is stored in its own source code repository, there will also tend to be less coupling, willy-nilly including of header files from other components, etc.  It helps people think in a more modular manner at the component level.  A component may be the Linux kernel, bootloader, each application in the system, etc.  A similar concept may be thinking about storing documents in hierarchical filesystem directory structure versus documents in a Wiki, which are stored in a flat structure and then organized by cross linking.  Yes, there are times to use a directory structure, but flexibility of a linked organization system (the essence of the Internet) is hard to beat.  Git submodules (or similar concepts) provides a similar linking method of organization.&lt;&#x2F;p&gt;
&lt;p&gt;With this in mind, we look at a build system as a way to collect a number of independent components and build them in a repeatable fashion.  While this may seem obvious to anyone somewhat familiar with OpenEmbedded, our vision is to extend this concept to easily facilitate product development so that we can move quickly and efficiently, but yet in a controlled and reliable way.  The first step is a new build template that is available &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.bec-systems.com&#x2F;cgit.cgi&#x2F;oe-build&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.  The following &lt;a href=&quot;&#x2F;video&#x2F;2010-06-04_bec-oe-build-template-1.ogv&quot;&gt;video&lt;&#x2F;a&gt; provides a short overview of how to use the build template (can be viewed in Firefox).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;video controls src=&quot;&#x2F;video&#x2F;2010-06-04_bec-oe-build-template-1.ogv&quot;&gt;&lt;&#x2F;video&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The functionality provided so far is fairly simple and provides a way to quickly set up a build environment.  With Git submodules, the versions of Bitbake and the OpenEmbedded are locked down.  Submodules are also used to provide an array of components to choose from, and the user initializes only the submodules they are interested in using.  The first example of this is providing both the recipe meta data from the OpenEmbedded project or the modified version from Gumstix.  In the future, examples will be provided for doing custom application and kernel development using the OE srctree and gitver classes.  Feedback is welcome; please let me know if you have questions or suggestions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MeeGo Review</title>
        <published>2010-06-02T00:00:00+00:00</published>
        <updated>2010-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/609/meego-review/"/>
        <id>https://bec-systems.com/609/meego-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/609/meego-review/">&lt;p&gt;As we evaluate various technologies that might be applicable in embedded systems, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;meego.com&#x2F;&quot;&gt;MeeGo&lt;&#x2F;a&gt; is the subject of this article.  MeeGo is a collaboration between Intel and Nokia, and is replacing the Moblin and Maemo efforts.  For this review, MeeGo was installed to a USB flash disk and booted on a Asus EEPC.  This was quite trivial to do, and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;meego.com&#x2F;devices&#x2F;netbook&#x2F;installing-meego-your-netbook&quot;&gt;instructions on the MeeGo website are very good&lt;&#x2F;a&gt;.  The following &lt;a href=&quot;&#x2F;video&#x2F;2010-06-01_meego_general.ogg&quot;&gt;video&lt;&#x2F;a&gt; (can be viewed in Firefox) provides a quick overview of the MeeGo Netbook UI.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;video controls src=&quot;&#x2F;video&#x2F;2010-06-01_meego_general.ogg&quot;&gt;&lt;&#x2F;video&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Overall, MeeGo looks interesting.  Hopefully with the collaboration between Intel and Nokia, there will emerge a number of components that become “standards” for embedded systems such as ways to manage wireless networks, cell phone radios, etc.  It would also be nice to have better options for implementing GUI’s on embedded devices with small screens.  While the MeeGo user interface is nice, it is not a radical departure from desktop applications.  Maemo (used on the Nokia N900) is more advanced in that it has optimized widgets for a small screen.  With Maemo, all applications run in a true full screen mode, which is generally desired for devices with smaller screens, or industrial devices where we want to keep user confusion to a minimum.  MeeGo applications seem to run full screen, but you can still drag them around, and some applications like the terminal do not start full screen.&lt;&#x2F;p&gt;
&lt;p&gt;It seems there is considerable interest in providing distributions based on MeeGo.  Novell has &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.novell.com&#x2F;news&#x2F;press&#x2F;novell-announces-support-for-meego&quot;&gt;announced&lt;&#x2F;a&gt; it plans to provide MeeGo based distributions for netbooks, and Intel &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;download.intel.com&#x2F;pressroom&#x2F;kits&#x2F;events&#x2F;computex2010&#x2F;pdf&#x2F;Computex_Day2_FactSheet.pdf&quot;&gt;claims&lt;&#x2F;a&gt; there are a number of other companies planning to build on top of MeeGo.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gumstix Overo review</title>
        <published>2010-02-08T00:00:00+00:00</published>
        <updated>2010-02-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/587/gumstix-overo-review/"/>
        <id>https://bec-systems.com/587/gumstix-overo-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/587/gumstix-overo-review/">&lt;p&gt;Based on the interest and number of embedded modules currently available, it appears that the OMAP3 CPU from TI will be very popular in the general purpose embedded Linux market.  One of the OMAP3 modules available is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.gumstix.com&#x2F;store&#x2F;catalog&#x2F;index.php?cPath=27_33&quot;&gt;Overo from Gumstix&lt;&#x2F;a&gt;.  As the company name suggests, this module looks about like a stick of gum, but smaller, as shown in the photo below.  The Gumstix module provides a lot of functionality in a very small package.  It is reasonably priced, and is an excellent way to quickly create a product that has advanced functionality such as a high powered CPU (OMAP3), high speed USB, DSP, 3-D graphics acceleration, etc.  For an example of the OMAP3 performance compared to previous generations of ARM processors, see &lt;a href=&quot;&#x2F;316&#x2F;gtk-performance-on-pxa270-vs-omap3&#x2F;&quot;&gt;this article&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2282_-1.jpg&quot; alt=&quot;Overo size comparison to a US dime&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The module contains all the core components, and can then be attached to a custom baseboard using the two high density connectors shown in the above photo.  There are 70 signals on each of the two connectors.  BEC &lt;a href=&quot;&#x2F;113&#x2F;gumstix-overo-connector-spreadsheet&#x2F;&quot;&gt;provides a spreadsheet&lt;&#x2F;a&gt; of the Overo signals to assist in designing a custom baseboard.&lt;&#x2F;p&gt;
&lt;p&gt;Due to the high level of component integration, the Overo has very few components on the module.  As shown in the below photo, there are really only 3 major visible components.  The flash and RAM is stacked on top of the CPU.  The PMIC contains all the required power managment circuitry, as well as Audio and USB interfacing functionality.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2281_1-1.jpg&quot; alt=&quot;Major components on the Gumstix Overo&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Overo module must be used with a baseboard.  Gumstix provides several development baseboards.  For production, a custom baseboard is typically created.  The Gumstix baseboards are reasonable cost, so they could be used for prototyping or low volume production if they have the required functionality.  Below is a photo of the Summit baseboard that provides DVI video out, audio, USB host and OTG, and an expansion connector with a number of signals.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2284_-1.jpg&quot; alt=&quot;Gumstix Summit baseboard (overo is not installed)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Below is the Palo baseboard from Gumstix that can be used to interface with a LCD display.  The Palo board contains a resistive touch screen controller, and circuitry required to interface with a LCD.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2283_1-1.jpg&quot; alt=&quot;Palo baseboard with Overo installed&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2276_-1.jpg&quot; alt=&quot;Display connected to Palo baseboard.  Note the tape applied to the display to keep from shorting to components on baseboard.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Overo does not include an Ethernet controller, so you typically use a USB-Ethernet adapter for development.  Below shows a typical development setup.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2273_-1.jpg&quot; alt=&quot;Typical USB-Ethernet connection through a USB hub.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One of the things about the OMAP3 that makes it very attractive for embedded development is the amount of software support, and the number of development and production solutions available.  The OMAP3 is very well supported by the OpenEmbedded project, and TI is very active in making contributions to various open source projects.  This greatly increases the quality and availability of advanced software functionality needed to support a complex system like the OMAP3.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2285_-1.jpg&quot; alt=&quot;Size comparison of several OMAP3 systems&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2286_-1.jpg&quot; alt=&quot;WIFI and BT antennas connected to Overo module&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many options for software development with the OMAP3 systems.  Below is a photo of a very simple Qt application.  GTK+ and Enlightenment are other popular GUI toolkits.  With 256MB of both flash and RAM, this is more than enough memory for most embedded applications, and provides plenty of headroom for adding features for future product revisions.  The Overo has the CPU processing capability to run advanced GUI applications with 3-D affects, as well as advanced web application frameworks like web2py that previous generations of ARM CPUs could not effectively run.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2287_-1.jpg&quot; alt=&quot;A simple Qt application that controls LEDs and reads user switch&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Gumstix Overo provides an excellent value for developing advanced products.  Especially for low volume products, when you compare the effort and time required to develop a full custom OMAP3 solution versus a simple Overo baseboard, using a module can provide significant advantages in terms of time to market, and development cost.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Go language for embedded systems</title>
        <published>2010-01-06T00:00:00+00:00</published>
        <updated>2010-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/579/the-go-language-for-embedded-systems/"/>
        <id>https://bec-systems.com/579/the-go-language-for-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/579/the-go-language-for-embedded-systems/">&lt;p&gt;As one of the things I do is evaluate new technologies for embedded systems, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go language&lt;&#x2F;a&gt; from Google is an interesting development.  I have been looking for a better “system” language for some time.  What I mean by a better system language is one that is nearly as efficient as C, does not require a large runtime, has a fast start-up time, and yet supports modern language features.  It is interesting that the constraints for very high performance server applications are often similar to those found in embedded systems in that applications must make very efficient use of memory and CPU cycles.  This is why C++ is still used a lot by Google and is also popular in embedded systems, but is not as common in applications where CPU power is plentiful compared to the resources to implement the application such as business applications.  One area of divergence is the focus on multi-core for high end server applications, but in the next few years, multi-core CPU’s such as the Atom and ARM Cortex-A9 will likely be common in low power embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;There are other options.  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;live.gnome.org&#x2F;Vala&quot;&gt;Vala&lt;&#x2F;a&gt; is very nice to use, is efficient, offers advanced language features, and extensive language bindings.  Vala is being used to implement some of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;freesmartphone.org&quot;&gt;http:&#x2F;&#x2F;freesmartphone.org&lt;&#x2F;a&gt; software stack.  C&#x2F;C++ are the old standby languages, but are rather tedious to program in compared to some of the newer languages in that source and header files are separate, and memory management is manual.&lt;&#x2F;p&gt;
&lt;p&gt;My interest in Go at this time is for ARM systems, so I ran a few experiments.  From what I can tell, there does exist an ARM Go compiler that is able to produce ARM code, but it &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;golang-nuts&#x2F;browse_thread&#x2F;thread&#x2F;a36e6e2cb254ea36&#x2F;760ef589ad750958&quot;&gt;currently lacks support for EABI soft floating point&lt;&#x2F;a&gt;.  The lack of floating point support is pretty much a show stopper for now, but it is at least a start.  The following is an example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;export GOARCH=arm
cd $GOROOT&#x2F;src&#x2F;
.&#x2F;make-arm.bash

cd
(create the following source file: hello.go)

==================
package main
import &amp;quot;fmt&amp;quot;

func main() {
        fmt.Printf(&amp;quot;Hello, world\n&amp;quot;);
}
=================

5g hello.go   (5g is the ARM compiler)
5l hello.5
scp 5.out root@n900:  (copy to ARM system)
ssh root@n900
?:~# .&#x2F;5.out
Hello, world

(modify with floating point code)

==================
package main
import &amp;quot;fmt&amp;quot;

func main() {
        var f = 1.5;
        fmt.Printf(&amp;quot;Hello, world\n&amp;quot;);
        fmt.Printf(&amp;quot;float f = %f\n&amp;quot;, f);
}

=================

(now run on ARM system)
?:~# .&#x2F;5.out
Segmentation fault
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As, you can see, floating point does not work as expected.  I’m not sure yet if gogcc can be configured to compile ARM binaries.  The other area where Go appears to need a lot of work is bindings to various libraries.  Though it does not appear to be ready for embedded ARM systems at this time, Go will be an interesting language to watch over the next few years.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded development activity</title>
        <published>2009-12-29T00:00:00+00:00</published>
        <updated>2009-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/576/openembedded-development-activity/"/>
        <id>https://bec-systems.com/576/openembedded-development-activity/</id>
        
        <content type="html" xml:base="https://bec-systems.com/576/openembedded-development-activity/">&lt;p&gt;Ever since I have been sending out &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;search.gmane.org&#x2F;?query=weekly+changelog&amp;amp;author=&amp;amp;group=gmane.comp.handhelds.openembedded&amp;amp;sort=date&amp;amp;DEFAULTOP=and&amp;amp;xP=Zweek%09Zchangelog&amp;amp;xFILTERS=Gcomp.handhelds.openembedded---A&quot;&gt;weekly change logs&lt;&#x2F;a&gt;, I have been impressed by the consistent amount of development activity in the OpenEmbedded project.  Every week there are consistently over a dozen developers making changes.  Developers come and go, but the contribution level always seems healthy.  While this amount of development leads to some amount of churn and issues, this amount of development is also required to keep pace with all the new developments in the OSS space.  Not having to wait 2 years for the next big release is one of the big advantages of using Linux and OpenEmbedded.  Having access to the latest technology provides a competitive advantage for many products, and makes dealing with the occasional issues that come up an acceptable trade-off.  Coupled with a flexible and consistent build system, OpenEmbedded is the vehicle to build advanced products.  Yes, its hard.  Yes, you better budget for some system software development time.  Yes, you should get some help if you’re not an embedded Linux expert.  Yes, you can start with some canned vendor “BSP” that seems to work and is seemingly the low-cost way to go, but eventually you’ll hit a brick wall where you need some bit of functionality that is not there, and then you’ll start up the exponential curve of dumping lots of time into trying to make something work with little progress forward.  It is much better to count the cost up front, and do things right.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OMAP3 Resume Timing</title>
        <published>2009-12-07T00:00:00+00:00</published>
        <updated>2009-12-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/569/omap3-resume-timing/"/>
        <id>https://bec-systems.com/569/omap3-resume-timing/</id>
        
        <content type="html" xml:base="https://bec-systems.com/569/omap3-resume-timing/">&lt;p&gt;One of the most common power management modes for ARM processors is the suspend mode.  In this mode, peripherals are shut down when possible, the SDRAM is put into self-refresh, and the CPU is placed in a low power mode.  A useful bit of information is to know how soon the system can respond to a resume (wake) event.&lt;&#x2F;p&gt;
&lt;p&gt;It turns out the answer to this question depends on where you want to do the work.  In the first test, I created a simple application that continuously toggled a GPIO.  This is an easy way to tell determine with a scope when the application was running.  I then measured the time between the wake event, and when this application signal started toggling.  It was a consistent 180ms.&lt;&#x2F;p&gt;
&lt;p&gt;For the next test I simply toggled a gpio in the &lt;em&gt;omap3_pm_suspend()&lt;&#x2F;em&gt; first thing after resume.  This tells me roughly how fast I can execute code in the kernel after a wake event.  This turned out to be 250uS.&lt;&#x2F;p&gt;
&lt;p&gt;So the good news is we can run kernel code very quickly after a resume event (250uS), but it currently takes a long time until user space processes start running again (180mS).  The 180ms can likely be reduced with some work, but this at least gives us a baseline.  180ms is fairly quick from a human perspective (seems pretty much instant), but for industrial devices that are responding to real-world events, then 180mS can be a long time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux kernel stats, and long term advantages</title>
        <published>2009-12-01T00:00:00+00:00</published>
        <updated>2009-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/564/linux-kernel-stats-advantages-and-long-term-advantages/"/>
        <id>https://bec-systems.com/564/linux-kernel-stats-advantages-and-long-term-advantages/</id>
        
        <content type="html" xml:base="https://bec-systems.com/564/linux-kernel-stats-advantages-and-long-term-advantages/">&lt;p&gt;I just read an interesting &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;howsoftwareisbuilt.com&#x2F;2009&#x2F;11&#x2F;18&#x2F;interview-with-greg-kroah-hartman-linux-kernel-devmaintainer&#x2F;&quot;&gt;interview&lt;&#x2F;a&gt; with Greg Kroah Hartman.  According to Greg, we add 11,000 lines, remove 5500 lines, and modify 2200 lines every single day.  This rate of change is something that few organizations have the resources to match.  It is interesting that Google chose to use the Linux kernel in the Android project even though they implemented most other parts of the system.  Another interesting thing to consider is the consequences of the Linux kernel license, which requires many drivers to be released as GPL.  While initially, this may be viewed as a disadvantage, it leads to some interesting long-term implications.  The obvious effect is that most Linux driver code is maintained in the mainline kernel source.  This leads to other effects.  One is that things are allowed to change, and get better.  The USB stack in both Linux and Windows has been re-written several times, but the difference is that in Linux the old software does not need to be maintained, as most drivers are maintained in the kernel, and can simply be modified along with core changes.  Another advantage is that drivers tend to be much simpler as common code is merged.  As a result, a Linux driver tends to be about 1&#x2F;3 the size of a driver in other operating systems.  Yes, getting driver code accepted in the mainline kernel can be difficult at times, but it is clearly the best long-term option.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux PM: OMAP3 Suspend Support</title>
        <published>2009-11-23T00:00:00+00:00</published>
        <updated>2009-11-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/551/linux-pm-omap3-suspend-support/"/>
        <id>https://bec-systems.com/551/linux-pm-omap3-suspend-support/</id>
        
        <content type="html" xml:base="https://bec-systems.com/551/linux-pm-omap3-suspend-support/">&lt;p&gt;This article provides an overview of the Linux kernel support for the suspend state in the TI OMAP3.  Power management has always been one of the more difficult parts of a system to get right.  The OMAP3 power management is quite extensive.  There are many levels of very granular control over the entire system.  Initially, we are going to focus on a simple power state where we want to put the CPU in a low power mode (basically not doing anything), but resume very quickly once an event occurs and continue running applications where they left off.  This is typically called “Suspend”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;power-states&quot;&gt;Power States&lt;&#x2F;h2&gt;
&lt;p&gt;We must first match up terminology between the Linux kernel and the OMAP documentation.  The Linux kernel supports several suspend power states:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_ON&lt;&#x2F;strong&gt;: system is running&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_STANDBY&lt;&#x2F;strong&gt;: system is in a standby state.  This is typically implemented where the CPU is in a somewhat static state.  After all the peripherals have been shut down, and the memory put into self refresh, the CPU executes an instruction that puts the CPU into a low power state.  After the next wake-event occurs, the CPU resumes operating at the next instruction.  The CPU state is static in this case.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_MEM&lt;&#x2F;strong&gt;: This goes one step beyond STANDBY in that the CPU is completely powered down and loses its state.  Any CPU state that needs to be saved is stored to SDRAM (which is in self refresh), or some other static memory.  When the system resumes, it has to boot through the reset vector.  The bootloader determines that the system was sleeping, and re-initializes the system, enables the SDRAM, restores whatever state is needed, and then jumps to a vector in the kernel to finish the resume sequence.  This mode is fairly difficult to implement as it involves the bootloader, and a lot of complex initialization code that is difficult to debug.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_MAX&lt;&#x2F;strong&gt;: From browsing the kernel source code, it appears this state is used for “Off” or perhaps suspend to disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The OMAP3 documentation uses the following terms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SLM&lt;&#x2F;strong&gt;: Static Leakage Management.  Includes “suspend” functionality.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Standby&lt;&#x2F;strong&gt;:  OMAP3x retains internal memory and logic.  (uses 7mW)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Device Off&lt;&#x2F;strong&gt;: System state is saved to external memory(0.590mW).  This could theoretically map to the PM_SUSPEND_MEM state.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;WFI&lt;&#x2F;strong&gt;: Wait for Interrupt.  This is an ARM instruction that puts the CPU in the standby state.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Based on the source code in the Linux kernel, there is currently only support for the Standby state:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;static int omap3_pm_enter(suspend_state_t unused)
{
	int ret = 0;

switch (suspend_state) {
	case PM_SUSPEND_STANDBY:
	case PM_SUSPEND_MEM:
		ret = omap3_pm_suspend();
		break;
	default:
		ret = -EINVAL;
	}

return ret;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;what-kernel-branches-versions-support-pm&quot;&gt;What kernel branches&#x2F;versions support PM&lt;&#x2F;h2&gt;
&lt;p&gt;Kevin Hilman has been maintaining an OMAP3 power management branch at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;khilman&#x2F;linux-omap-pm.git&quot;&gt;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;khilman&#x2F;linux-omap-pm.git&lt;&#x2F;a&gt;.  Bits are being merged upstream.  Some of the things that don’t seem to be merged yet are SmartReflex support, and a number of other details.  But, it seems that basic suspend&#x2F;resume support is available in the upcoming 2.6.32 kernel.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-details-on-the-standby-mechanism&quot;&gt;More Details on the Standby Mechanism&lt;&#x2F;h2&gt;
&lt;p&gt;Due to the granularity and complexity of the the OMAP3 power management, relevant pieces of documentation are scattered throughout the OMAP35x Technical Reference Manual.  The following were helpful:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Table 3-17: details the MPU subsystem operation power modes&lt;&#x2F;li&gt;
&lt;li&gt;Table 3-18: Power Mode Allowable Transitions.  Standby
mode can enter from active mode only by executing the wait for interruption (WFI) instruction.&lt;&#x2F;li&gt;
&lt;li&gt;SDRC, “Self Refresh Management”.  The OMAP3 can automatically put the SDRAM in self refresh mode when the CPU enters the idle state.&lt;&#x2F;li&gt;
&lt;li&gt;MPU Power Mode Transistions: The ARM core initiates entering into standby via software only (CP15 - WFI).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;em&gt;omap34xx_cpu_suspend&lt;&#x2F;em&gt; function is called to put the CPU into standby mode.  The actual instruction that stops the CPU is the ARM WFI (wait for interrupt) instruction.  This is a little different than previous generations of ARM CPUs that used coprocessor registers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h2&gt;
&lt;p&gt;With the 2.6.32-rcX kernels, suspend&#x2F;resume appears to work at least from the console:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@overo:~# echo mem &amp;gt; &#x2F;sys&#x2F;power&#x2F;state
PM: Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.00 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.00 seconds) done.
Suspending console(s) (use no_console_suspend to debug)

&amp;lt;after key press on serial console ...&amp;gt;

omapfb omapfb: timeout waiting for FRAME DONE
CLIFF: going into suspend
Wake up daisy chain activation failed.
CLIFF: returning from suspend
Successfully put all powerdomains to target state
Restarting tasks ...
done.
root@overo:~#
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The CLIFF messages are debug statements placed in the low-level suspend code to make sure we were getting to that point.  The console is disabled early in the suspend process, so we don’t get the debug messages until after resume.  The &lt;em&gt;no_console_suspend&lt;&#x2F;em&gt; kernel option can be used to leave the console enabled during suspend, but that feature does not seem to work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary-future-work&quot;&gt;Summary&#x2F;Future work&lt;&#x2F;h2&gt;
&lt;p&gt;This covers the basics of Linux Suspend&#x2F;Resume support for the OMAP3 CPU.  There are many more options and details such as configuring wake sources, dynamic power management while running, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Integrated CAN solutions for Linux</title>
        <published>2009-11-19T00:00:00+00:00</published>
        <updated>2009-11-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/544/integrated-can-solutions-for-linux/"/>
        <id>https://bec-systems.com/544/integrated-can-solutions-for-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/544/integrated-can-solutions-for-linux/">&lt;p&gt;I just received an email notification from EMS (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ems-wuensche.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;ems-wuensche.com&#x2F;&lt;&#x2F;a&gt;) that support for their CAN controllers is now in mainline Linux kernels.  The EMS PCI products are supported in 2.6.31, and the CPC-USB product will be supported in 2.6.32.  I’ve used various Linux CAN stacks in the past, but none were as well integrated as the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SocketCAN&quot;&gt;SocketCAN&lt;&#x2F;a&gt; solution that has been merged into the mainline Linux kernel.  Though I’ve not used the EMS products yet, the fact that support is in the mainline kernel source provides a good indication that they know how to do things correctly, and that the software is of good quality.&lt;&#x2F;p&gt;
&lt;p&gt;The Microchip MCP2515 is another option for interfacing CAN with a Linux system, but uses the SPI bus so it typically requires a custom hardware design.   The availability of a USB adapter provides an easy way for CAN to be used with about any existing Linux system including small embedded systems.  From looking at the kernel source code, it appears that EMS solutions use the SJA1000 CAN controller, which has been an industry standard controller for many years.&lt;&#x2F;p&gt;
&lt;p&gt;Message buffering is an important consideration when selecting a Linux CAN solution.  Often in a system, the Linux computer is responsible for data processing, user interface, and other CPU intensive operations.  The real-time control is often relegated to a separate microcontroller.  The CAN bus is then just a convenient and robust way to get data from the control part of the system to the data processing part.  The amount of hardware buffering in the CAN controller determines how quickly the system needs to respond to process the CAN data, so the CAN controller has space to receive new data.  The SJA1000 provides a 64-byte receive fifo, or roughly space for 4 CAN messages.  This provides a little more buffering than the 2 messages in the MCP2515.  Dealing with full bandwidth CAN data in a Linux system can be a challenge  with small amounts of buffering as you typically have to implement the Linux RT patch, and spend some time tuning it.  Another upcoming CAN solution that looks nice is the TI High End CAN Controller (HECC) found in the new Sitara CPUs.  This controller provides 32 hardware mailboxes which should provide even more buffering, which makes it even better suited for operating systems like Linux.  As with any technology, there are tradeoffs, so its nice to have options.&lt;&#x2F;p&gt;
&lt;p&gt;One area the EMS solution may be very useful is for prototyping and development.  The ideal development flow when developing an Embedded Linux product is to development as much as possible on a PC.  The EMS product allows you to easily implement SocketCAN functionality on a PC so you can talk to the rest of your system directly from a PC.  The final embedded solution may be based on a more cost effective solution like the MCP2515 or the TI HECC, but being able to interface to the rest of the system directly from a PC has the potential to improve development efficiency.  This is part of the “Big Win” with Embedded Linux where the same technology scales from the embedded system, to the PC, to the server.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notification at the end of builds</title>
        <published>2009-11-05T00:00:00+00:00</published>
        <updated>2009-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/540/notification-at-the-end-of-builds/"/>
        <id>https://bec-systems.com/540/notification-at-the-end-of-builds/</id>
        
        <content type="html" xml:base="https://bec-systems.com/540/notification-at-the-end-of-builds/">&lt;p&gt;I do quite a few OpenEmbedded project builds during the course of a week.  This process usually takes 3-5 minutes.  That is just enough time to get distracted doing something else and forget about the build until an hour later when you realize – oops, I was supposed to send out a release email once the build was finished and uploaded.  It occured to me that it would be nice if my computer played a distinct sound at the end of the build.  With Linux this is incredibly easy:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;wget http:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;7&#x2F;76&#x2F;Ding_Dong_Bell.ogg&lt;&#x2F;li&gt;
&lt;li&gt;sudo mv Ding_Dong_Bell.ogg &#x2F;usr&#x2F;local&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;sudo aptitude install cplay&lt;&#x2F;li&gt;
&lt;li&gt;sudo echo “cplay &#x2F;usr&#x2F;local&#x2F;Ding_Dong_Bell.ogg” &amp;gt; &#x2F;usr&#x2F;local&#x2F;bin&#x2F;bell&lt;&#x2F;li&gt;
&lt;li&gt;sudo chmod 775 &#x2F;usr&#x2F;local&#x2F;bin&#x2F;bell&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now, when I have a long build, I simply do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bitbake my-image; bell
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is probably something better than cplay that does not start a UI – any suggestions?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick serial logging application</title>
        <published>2009-10-21T00:00:00+00:00</published>
        <updated>2009-10-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/533/a-quick-serial-logging-application/"/>
        <id>https://bec-systems.com/533/a-quick-serial-logging-application/</id>
        
        <content type="html" xml:base="https://bec-systems.com/533/a-quick-serial-logging-application/">&lt;p&gt;Recently when debugging a device connected to a rs485 bus, I needed a simple application to dump the raw data coming over the rs485 bus.  Minicom does all kinds of weird terminal stuff, plus it will not display binary data, so that was out.  While looking for serial analyzer programs for Linux, and pondering writing my own simple C application, it occurred to me to use pyserial.  With a few lines of code, I got exactly what I needed:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;import serial
import sys
import struct

if len(sys.argv) != 3:
    print &amp;quot;Usage: serial-dump.py &amp;lt;serial port&amp;gt; &amp;lt;baud rate&amp;gt;&amp;quot;
    sys.exit(-1)

print &amp;quot;Dumping data on %s&amp;quot; % (sys.argv[1])

ser = serial.Serial(sys.argv[1], sys.argv[2], timeout=0.3)

while(1):
    buf = ser.read(500)
    if len(buf) &amp;gt; 0:
        print &amp;quot;Read %i bytes:&amp;quot; % (len(buf)),

for i in buf:
            value = struct.unpack(&amp;#39;B&amp;#39;, i)[0]
            print &amp;quot;%02x&amp;quot; % (value),

print &amp;quot;&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The full source is available &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;svn.bec-systems.com&#x2F;pub&#x2F;py-serial-dump&#x2F;serial-dump.py&quot;&gt;here&lt;&#x2F;a&gt;.  This could obviously be improved to do true blocking reads, automatically parse protocols, implement a gui, etc.  Ideas for efficiently reading data using pyserial is available in a &lt;a href=&quot;&#x2F;257&#x2F;tips-for-reading-a-serial-data-stream-in-python&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt;.  Another example of using a scripting language for quick tasks is &lt;a href=&quot;&#x2F;226&#x2F;a-really-nice-hex-calculator&#x2F;&quot;&gt;&#x2F;226&#x2F;a-really-nice-hex-calculator&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Apache and how to correctly use NameVirtualHost</title>
        <published>2009-10-16T00:00:00+00:00</published>
        <updated>2009-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/528/apache-and-how-to-correctly-use-namevirtualhost/"/>
        <id>https://bec-systems.com/528/apache-and-how-to-correctly-use-namevirtualhost/</id>
        
        <content type="html" xml:base="https://bec-systems.com/528/apache-and-how-to-correctly-use-namevirtualhost/">&lt;p&gt;As I often get involved in server administration (SVN, git, redmine, etc setup), I deal with Apache on a regular basis.  For simple configurations, the default Ubuntu&#x2F;debian config works well.  However, for a more complex setup with virtual hosts, multiple IP addresses, and SSL support, it is common to run into the following message:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;mixing * ports and non-* ports with a NameVirtualHost address is not supported, proceeding with undefined results&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Googling does not return a clear explanation to this problem, so that is why I’m writing this article. The impulsive approach of randomly changing things does not get you too far – especially with the Debian&#x2F;Ubuntu Apache configuration that is composed of seperate files for each virtual host.  After reading the documentation, things become clearer:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note that the argument to the &lt;code&gt;&amp;lt;VirtualHost&amp;gt;&lt;&#x2F;code&gt; directive must       exactly match the argument to the &lt;code&gt;NameVirtualHost&lt;&#x2F;code&gt; directive.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And, by considering the fact that the seperate virtual host config files really just get concatenated into one big file, it makes sense that you can’t have more than one NameVirtualHost entry.  Ubuntu by default puts the NameVirtualHost in the default virtual host file, which gets soft linked to sites-enabled&#x2F;000-default.  I presume the ‘000’ means it gets loaded first.  I find it much more intuitive to put the NameVitualHost directives in the &#x2F;etc&#x2F;apache2&#x2F;httpd.conf file.  This way it is clear that these entries are common to all virtual host entries.  So what I end up with is:&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;apache2&#x2F;httpd.conf&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;NameVirtualHost 74.208.184.45:80
NameVirtualHost 74.208.184.46:80
NameVirtualHost 74.208.184.45:443
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apache2&#x2F;sites-available&#x2F;bec-systems.com&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.45:80&amp;gt;
        ServerName bec-systems.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apach2&#x2F;sites-available&#x2F;bec-systems.com.ssl&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.45:443&amp;gt;
        ServerName bec-systems.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apach2&#x2F;sites-available&#x2F;svn.bec-systems.com&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.45:80&amp;gt;
        ServerName svn.bec-systems.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apach2&#x2F;sites-available&#x2F;site2.com (with different IP address)&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.46:80&amp;gt;
        ServerName site2.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Again, the points to remember are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The argument to VirtualHost must match a NameVirtualHost directive&lt;&#x2F;li&gt;
&lt;li&gt;the NameVirtualHost directive is common, so there should only be one entry&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for kernel development with OpenEmbedded</title>
        <published>2009-10-13T00:00:00+00:00</published>
        <updated>2009-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/521/best-practices-for-kernel-development-with-openembedded/"/>
        <id>https://bec-systems.com/521/best-practices-for-kernel-development-with-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/521/best-practices-for-kernel-development-with-openembedded/">&lt;p&gt;A common question is how do you do kernel development with OpenEmbedded?  Typically, OpenEmbedded builds a kernel by checking the source out of a git repository, or by applying patch files to a released version of the kernel.  See the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&quot;&gt;many recipes&lt;&#x2F;a&gt; for examples.  This works very well for a Linux distribution build system, but is less than ideal for ongoing kernel development where you will have many iterations over a period of time. The OE work directory is considered transient, and should not be used for any ongoing development.  Fortunately, the kernel build system is self contained, so it is a very simple matter to reference the toolchain built by OpenEmbedded and work outside the OpenEmbedded build system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-git&quot;&gt;Use Git&lt;&#x2F;h2&gt;
&lt;p&gt;Trust me on this one, just use it!  It will make your life easier.  There is a learning curve to any powerful tool.  Another way to state this is if a tool does not do much, then it would be easy to learn.  So expect to spend a little time learning to use git.  With modern Linux kernel development, much of your time is spent integrating work that others are doing.  For example, if you are using the OMAP3 CPU, you might want to start with linux-omap branch, integrate some patches from the OE beagleboard build, merge the OMAP PM tree, and then merge some bits from the Linux-wireless tree.  This is the way embedded Linux development is done today.  Git makes it possible to have many parallel developments going at their own pace, including your own.  Even in your own development, you will find significant advantages to being able to quickly create and merge branches, revise commits, etc.  There are several &lt;a href=&quot;&#x2F;tags&#x2F;git&#x2F;&quot;&gt;articles about git&lt;&#x2F;a&gt; on this site.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;importing-an-oe-kernel-into-git&quot;&gt;Importing an OE kernel into git&lt;&#x2F;h2&gt;
&lt;p&gt;If you are starting with an existing OE kernel tree, then you typically need to set up an equivalent tree in your local git workspace.  Typically you just look at the recipe to see how to manually reconstruct it.  For example, lets consider the SRC_URI from the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux-palm-omap1_2.6.22-omap1.bb&quot;&gt;palm-omap1&lt;&#x2F;a&gt; recipe:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI = &amp;quot;${KERNELORG_MIRROR}&#x2F;pub&#x2F;linux&#x2F;kernel&#x2F;v2.6&#x2F;linux-2.6.22.tar.bz2 \
           http:&#x2F;&#x2F;www.muru.com&#x2F;linux&#x2F;omap&#x2F;patches&#x2F;patch-2.6.22-omap1.bz2;patch=1 \
	   file:&#x2F;&#x2F;defconfig&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To set this kernel up in git, we might do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;git clone git:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux-2.6.git&lt;&#x2F;li&gt;
&lt;li&gt;cd linux-2.6&lt;&#x2F;li&gt;
&lt;li&gt;git checkout -b my_branch v2.6.22&lt;&#x2F;li&gt;
&lt;li&gt;wge&lt;code&gt;t http:&#x2F;&#x2F;www.muru.com&#x2F;linux&#x2F;omap&#x2F;patches&#x2F;patch-2.6.22-omap1.bz2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;bzip2 -d patch-2.6.22-omap1.bz2&lt;&#x2F;li&gt;
&lt;li&gt;git am patch-2.6.22-omap1&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If the git am fails, then you might need to add a subject and author line to the patch in the following form and then retry git am.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;From: Name &amp;lt;name@company.com&amp;gt;
Subject: omap1 patch
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now when you do a git log, you will see the above patch applied.  git apply can also be used to apply patches, but I prefer git-am as it automatically handles new files and fills in the commit message and author.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-the-toolchain&quot;&gt;Setting up the toolchain&lt;&#x2F;h2&gt;
&lt;p&gt;Now that you have a kernel, you must set up a toolchain so you can build it.  I typically set up my kernel directory next to my OE build directory in my project space, so I can then source the following &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;oe&#x2F;scripts&#x2F;setup-env&quot;&gt;script&lt;&#x2F;a&gt; to set up the toolchain:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;CROSS_COMPILER_PATH=`cd ..&#x2F;oe&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;cross&#x2F;armv7a&#x2F;bin; pwd`
BUILD_ARCH=`uname -m`
OE_STAGING_PATH=`cd ..&#x2F;oe&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;staging&#x2F;${BUILD_ARCH}-linux&#x2F;usr&#x2F;bin; pwd`
STAGING_KERNEL_DIR=`cd linux-2.6; pwd`
export PATH=$PATH:$CROSS_COMPILER_PATH:$OE_STAGING_PATH
export ARCH=arm
export CROSS_COMPILE=arm-angstrom-linux-gnueabi-
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Adjust to whatever you are building for.  Now you can simply type make.  The reason the OE_STAGING_PATH is added to the PATH in the above example is so that the uboot mkimage utility can be used directly from the OE build if your build target is make uImage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-modules&quot;&gt;Installing modules&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes you need to re-install all modules on the target because you changed kernel version, etc.  Typically OE packages up all modules and adds the one you specify to the rootfs.  Because we are building the kernel outside the OE directory, OE can no longer do this.  However, its still very easy to install modules from your kernel development directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;rm -rf modules_install; INSTALL_MOD_PATH=modules_install make modules_install
rsync -av modules_install&#x2F;lib&#x2F;modules&#x2F;2.6.22 root@192.168.1.115:&#x2F;lib&#x2F;modules&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first command installs the modules to a temporary directory, and the second command rsync’s the modules to your target system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-a-kernel-recipe-with-your-changes&quot;&gt;Creating a kernel recipe with your changes&lt;&#x2F;h2&gt;
&lt;p&gt;Once you get to the point where you want to create a recipe with your changes, you can easily export a patch, or series of patches using git diff or git format-patch.  Simply add the patch files to your kernel recipe SRC_URI.  You can also teach bitbake to fetch your kernel source directly from a git repository, but I’ve generally found the patch mechanism to be adequate and easier in most cases.  As an example, you can create one large patch with all your changes that can be applied on the 2.6.22 released kernel:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git diff HEAD..v2.6.22 &amp;gt; my_kernel_changes.patch
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;other-ways&quot;&gt;Other ways …&lt;&#x2F;h2&gt;
&lt;p&gt;This is just one flow and there are many variations.  There is also a  new mechanism in OpenEmbedded called srctree that allows you to use OpenEmbedded in an external source tree.  srctree has the potential to further streamline this type of development.&lt;&#x2F;p&gt;
&lt;p&gt;As with any task, you want to use the tools that make sense for the task.  OpenEmbedded makes sense for building Linux distributions, but it is not a kernel development tool.  Git and the kernel build system make sense for kernel development.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>converting digital camera movies to ogg format</title>
        <published>2009-09-09T00:00:00+00:00</published>
        <updated>2009-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/514/converting-digital-camera-movies-to-ogg-format/"/>
        <id>https://bec-systems.com/514/converting-digital-camera-movies-to-ogg-format/</id>
        
        <content type="html" xml:base="https://bec-systems.com/514/converting-digital-camera-movies-to-ogg-format/">&lt;p&gt;Now that firefox (v3.5) has built in support for ogg videos, ogg is now the most convenient format for “easy to view” video files (assuming you don’t want to use a service like youtube).  Some digital cameras (like my Canon) records movies in AVI format.  I created a script that uses gstreamer to convert the AVI file to an ogg file for easy viewing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;avi_to_ogg&#x2F;avi_to_ogg&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;avi_to_ogg&#x2F;avi_to_ogg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And some of the results:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;video&#x2F;&quot;&gt;&#x2F;video&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(hint, download firefox 3.5 to view these videos)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for building Gtk+ applications with OpenEmbedded</title>
        <published>2009-09-08T00:00:00+00:00</published>
        <updated>2009-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/509/best-practices-for-building-gtk-applications-with-openembedded/"/>
        <id>https://bec-systems.com/509/best-practices-for-building-gtk-applications-with-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/509/best-practices-for-building-gtk-applications-with-openembedded/">&lt;p&gt;I recently&lt;a href=&quot;&#x2F;501&#x2F;best-practices-for-building-qt-applications-with-openembedded&#x2F;&quot;&gt;wrote an article about best practices building Qt applications with OpenEmbedded&lt;&#x2F;a&gt;, and it occured to me that I should write an equivalent article for Gtk+ applications.  The same points apply – put your application source in a SCM system, and put the install logic in the application source (read the above article).  The difference is that Gtk applications typically use autotools where Qt applications use qmake to build the application.  This article details how a minimal GTK+ application should be set up and built using OpenEmbedded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;application-source&quot;&gt;Application Source&lt;&#x2F;h2&gt;
&lt;p&gt;I created a sample GTK hello application located at: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&#x2F;&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&lt;&#x2F;a&gt;.  This is a SVN repository, so you can simply “svn co” the above URI to check out the code.  If you are running Ubuntu, you can install the necessary tools to build a native Gtk+ application by:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;sudo apt-get install libgtk2.0-dev build-essential autoconf automake pkg-config&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To build on your x86 Linux PC, run the following steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;svn co  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&#x2F;&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;cd gtk_hello&lt;&#x2F;li&gt;
&lt;li&gt;autoreconf -i&lt;&#x2F;li&gt;
&lt;li&gt;.&#x2F;configure --prefix=`pwd`&#x2F;install&lt;&#x2F;li&gt;
&lt;li&gt;make install&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This compiles and installs the application in to the “install” directory.  If you look in this directory, you will notice the application binary is installed in the “install&#x2F;bin” directory.  Typically, the install directory is set to &#x2F;usr&#x2F;bin, but in this example we set it to install so we don’t need to run “make install” as root, but yet we can verify the install logic works properly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openembedded-recipe&quot;&gt;OpenEmbedded Recipe&lt;&#x2F;h2&gt;
&lt;p&gt;Now that you have verified the application builds and installs properly on a x86 PC, it is trivial to build the application in OpenEmbedded.  Create a recipe in your OE recipes directory named &lt;em&gt;gtk-hello_svn.bb&lt;&#x2F;em&gt; with the following contents:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DESCRIPTION = &amp;quot;Sample Gtk+ Hello application, used to demonstrate build system&amp;quot;
AUTHOR = &amp;quot;Cliff Brake &amp;lt;cbrake@bec-systems.com&amp;gt;&amp;quot;

SRCREV = &amp;quot;17&amp;quot;
PV = &amp;quot;0.0+svn${SRCREV}&amp;quot;
PR = &amp;quot;r0&amp;quot;

DEPENDS = &amp;quot;gtk+&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub;module=gtk_hello;proto=http;rev=17&amp;quot;

S = &amp;quot;${WORKDIR}&#x2F;gtk_hello&#x2F;&amp;quot;

inherit autotools
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, run: bitbake gtk-hello.  That is it!  Building Linux applications is easy if you simply use the tools, whether it be autotools, qmake, etc.  Too often there is the tendency to set up your own compile steps with ${CC} variables, etc.  While this seems to be the simple approach at first glance (autotools is too hard), it quickly becomes unmaintainable and in the end is a lot more work than simply learning the basics of the industry standard tools.  See &lt;a href=&quot;&#x2F;121&#x2F;autotools-quick-reference&#x2F;&quot;&gt;previous autotools article&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for building Qt applications with OpenEmbedded</title>
        <published>2009-08-06T00:00:00+00:00</published>
        <updated>2009-08-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/501/best-practices-for-building-qt-applications-with-openembedded/"/>
        <id>https://bec-systems.com/501/best-practices-for-building-qt-applications-with-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/501/best-practices-for-building-qt-applications-with-openembedded/">&lt;p&gt;This article describes how to cross compile a Qt application (named qt_tutorial) with OpenEmbedded, and several best practices you should consider.  OpenEmbedded currently includes &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;qt4&quot;&gt;fairly good support for building Qt&lt;&#x2F;a&gt; – both Qt Embedded and Qt X11.   OE also includes a number of &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;classes&quot;&gt;qt classes&lt;&#x2F;a&gt; that make building Qt applications easy.  One of the main considerations with embedded Linux application development is that you keep the build system flexible so that you can easily build on a PC or for your embedded hardware.  This means that hand crafted Makefiles with hardcoded paths to cross compilers do not quality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;put-your-application-in-a-scm-system&quot;&gt;Put Your Application in a SCM system&lt;&#x2F;h2&gt;
&lt;p&gt;No matter what type of application you are building, it is a good idea to put your source in a SCM or revision control system and fetch it directly using OE.  OpenEmbedded supports fetching sources from a number of revision control systems including Subversion, Git, Bazaar, Mercurial, CVS, etc.   The not so obvious reason we do this is so you can easily check out the source code and build it on a PC as well as your target system in OE.  In this example we fetch the application source from a SVN repository:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI = &amp;quot;svn:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub;module=qt_tutorial;proto=http&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the above repository, the direct URI to the source would be: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;qt_tutorial&#x2F;&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;qt_tutorial&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;put-the-install-logic-in-the-application-source&quot;&gt;Put the Install logic in the Application Source&lt;&#x2F;h2&gt;
&lt;p&gt;Most Linux applications support “make install”, and this is the case with autotools, and qmake (Qt’s build tool).  We could put logic in the OE recipe to install the application something like the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;do_install() {
	install -d ${D}&#x2F;${bindir}
	install -m 0755  ${S}&#x2F;qt_tutorial ${D}&#x2F;${bindir}
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But, the problem with this approach is you can’t install the application in other environments (like a native x86 PC build) unless you are building with OE.  So a better approach is to put the logic to install the application in the application source, so that in can be installed in both your PC environment, and your OpenEmbedded build.  To accomplish this, you can set up the project as follows&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;application qmake project file (qt_tutorial.pro):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;TEMPLATE = app
TARGET = qt_tutorial
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += lcdrange.h
SOURCES += lcdrange.cpp main.cpp

target.path = &#x2F;usr&#x2F;bin
INSTALLS += target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;OpenEmbedded recipe (qt-tutorial_svn.bb):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;inherit qt4e

SRCREV = &amp;quot;${AUTOREV}&amp;quot;
PV = &amp;quot;1.0+svnr${SRCREV}&amp;quot;
PR = &amp;quot;r1&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub;module=qt_tutorial;proto=http&amp;quot;

S = ${WORKDIR}&#x2F;qt_tutorial

FILES_${PN}-dbg += &amp;quot;${bindir}&#x2F;.debug&amp;quot;

do_install() {
	export INSTALL_ROOT=${D}
	make install
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, the same mechanism is used to install the application on both a PC native build, as well an OpenEmbedded build.  If you look in the Makefile generated by qmake, you see the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;install_target: first FORCE
	@$(CHK_DIR_EXISTS) $(INSTALL_ROOT)&#x2F;usr&#x2F;bin&#x2F; || $(MKDIR) $(INSTALL_ROOT)&#x2F;usr&#x2F;bin&#x2F;
	-$(INSTALL_PROGRAM) &amp;quot;$(QMAKE_TARGET)&amp;quot; &amp;quot;$(INSTALL_ROOT)&#x2F;usr&#x2F;bin&#x2F;$(QMAKE_TARGET)&amp;quot;

install:  install_target  FORCE
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;INSTALL_ROOT can be set to force the entire system to be installed in a subdirectory.  This is required for build systems that generate packages, like OpenEmbedded.  To build this example, put the qt-tutorial_svn.bb file in your OE recipes tree, and run: bitbake qt-tutorial.  This will fetch the source code and build a package.  To run the tutorial, install the package on a system that includes Qt Embedded, and then run: qt_tutorial -qws.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gumstix Overo Pinout Spreadsheet updated</title>
        <published>2009-07-30T00:00:00+00:00</published>
        <updated>2009-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/491/gumstix-overo-pinout-spreadsheet-updated/"/>
        <id>https://bec-systems.com/491/gumstix-overo-pinout-spreadsheet-updated/</id>
        
        <content type="html" xml:base="https://bec-systems.com/491/gumstix-overo-pinout-spreadsheet-updated/">&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;redmine.bec-systems.com&#x2F;bec&#x2F;documents&#x2F;1&quot;&gt;Gumstix Overo Pinout Spreadsheet&lt;&#x2F;a&gt; has been updated with the Palo board connector pinouts, and a few mistakes have been fixed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;overo_pinout2-1.png&quot; alt=&quot;overo_pinout2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;overo_pinout-1.png&quot; alt=&quot;overo_pinout&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to capture source changes to an OpenEmbedded package</title>
        <published>2009-07-14T00:00:00+00:00</published>
        <updated>2009-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/456/capture-oe-source-changes/"/>
        <id>https://bec-systems.com/456/capture-oe-source-changes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/456/capture-oe-source-changes/">&lt;p&gt;One task that is a often confusing to new OpenEmbedded users is how to capture changes to the source code for a package&#x2F;recipe.  First, lets review the progression in tools use to capture source code changes.&lt;&#x2F;p&gt;
&lt;figure&gt;&lt;img title=&quot;patch_quilt_git1&quot; src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;patch_quilt_git1-1.png&quot; alt=&quot;Progression of tools&quot;&gt;&lt;figcaption&gt;Figure 1: Progression of tools&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;In days of yore, developers often used gnu diff to capture modifications to a source tree.  The typical practice was to create two source trees: a pristine, and a dirty tree.  Modifications were made in the dirty tree, and periodically gnu diff was run between the two trees to capture the changes.  Then came quilt which allowed you to capture changes without a pristine tree – kind of a cheap version control system.  The typical flow was:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cd &lt;source dir&gt;&lt;&#x2F;li&gt;
&lt;li&gt;quilt new my_changes.patch&lt;&#x2F;li&gt;
&lt;li&gt;quilt add file1.c&lt;&#x2F;li&gt;
&lt;li&gt;edit file1.c&lt;&#x2F;li&gt;
&lt;li&gt;quilt refresh (now my_changes.patch records the edits to file1.c)&lt;&#x2F;li&gt;
&lt;li&gt;debug&lt;&#x2F;li&gt;
&lt;li&gt;edit file2.c&lt;&#x2F;li&gt;
&lt;li&gt;(oops forget to quilt add file2.c – now what ….)&lt;&#x2F;li&gt;
&lt;li&gt;restore file2.c from pristine source&lt;&#x2F;li&gt;
&lt;li&gt;quilt add file2.c&lt;&#x2F;li&gt;
&lt;li&gt;edit file2.c&lt;&#x2F;li&gt;
&lt;li&gt;quilt refresh&lt;&#x2F;li&gt;
&lt;li&gt;(now my_changes.patch records edits to file1.c and file2.c)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As you can see, things are much better than plain diff, but you still have to keep track of the files you edit.  With git, we can do essentially the same things, only git keeps track of the files you edit, plus it is easier to organize patch files.  The flow with git is something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cd &lt;source dir&gt;&lt;&#x2F;li&gt;
&lt;li&gt;git init&lt;&#x2F;li&gt;
&lt;li&gt;git add *&lt;&#x2F;li&gt;
&lt;li&gt;git commit (now the entire source tree is recorded by git)&lt;&#x2F;li&gt;
&lt;li&gt;edit file1.c&lt;&#x2F;li&gt;
&lt;li&gt;edit file2.c ….&lt;&#x2F;li&gt;
&lt;li&gt;git status (shows you files that were modified)&lt;&#x2F;li&gt;
&lt;li&gt;git add file1.c file2.c&lt;&#x2F;li&gt;
&lt;li&gt;git commit&lt;&#x2F;li&gt;
&lt;li&gt;git log (shows you changes you have made)&lt;&#x2F;li&gt;
&lt;li&gt;git format-patch HEAD~1 (outputs the patch created by the last commit)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Once your source code is in git, then you can do all kinds of fancy things like merging, re-ordering, and re-naming patch files with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;software&#x2F;scm&#x2F;git-core&#x2F;docs&#x2F;git-rebase.html&quot;&gt;git-rebase --interactive&lt;&#x2F;a&gt; command.&lt;&#x2F;p&gt;
&lt;p&gt;One of the uses of this technique is when you need to record a small change to a package source in a build system such as OpenEmbedded, and apply that change for subsequent builds.  In this case you might do something like the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;bitbake -c devshell &amp;lt;recipe_to_patch&amp;gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;in devshell capture changes in git as shown above to create &lt;em&gt;my_changes.patch&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;cp my_changes.patch &amp;lt;oe_tree&amp;gt;&#x2F;recipes&#x2F;&amp;lt;recipe_to_change&amp;gt;&#x2F;files&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;edit &amp;lt;oe_tree&amp;gt;&#x2F;recipes&#x2F;&amp;lt;recipe_to_change&amp;gt;&#x2F;&amp;lt;recipe_to_change&amp;gt;.bb&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;tell bitbake to apply the patch when building the recipe: SRC_URI += “file:&#x2F;&#x2F;my_changes.patch;patch=1”&lt;&#x2F;li&gt;
&lt;li&gt;increment the PR variable so that bitbake knows to rebuild the recipe.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Figure 2 illustrates the above steps.&lt;&#x2F;p&gt;
&lt;figure&gt;&lt;img title=&quot;oe_patch_flow1&quot; src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;oe_patch_flow1-1.png&quot; alt=&quot;Flow to capture packages source changes in OpenEmbedded&quot;&gt;&lt;figcaption&gt;Figure 2: Flow to capture package source changes in OpenEmbedded&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;While the above steps might seem overly complex, you must consider what you are trying to do.  Building a Linux distribution is not a simple task.  We are dealing with large amounts of source code from many different projects.  Putting all this source code in one tree is not an option, because then we would be defeating the very reasons open source is attractive in the first place: flexibility, largly decoupled projects, advanced technology, fast bug fixes, many options to choose from, developer support, etc. Each open source project must remain a self contained project that is largly decoupled from other projects so it can develop at its own pace.  It is for these reasons that open source technologies are used to give products a competitive edge.  So, like any complex process or task, there must be some understanding of how it works, an appreciation for what it can do for you, and an investment in tools and techniques required to be effective.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;update 2023-09-23&lt;&#x2F;strong&gt;: &lt;code&gt;recipetool&lt;&#x2F;code&gt; and &lt;code&gt;devtool&lt;&#x2F;code&gt; are updated tools that can be used to make and capture changes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded Linux versus Windows CE</title>
        <published>2009-06-20T00:00:00+00:00</published>
        <updated>2009-06-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/462/embedded-linux-versus-windows-ce/"/>
        <id>https://bec-systems.com/462/embedded-linux-versus-windows-ce/</id>
        
        <content type="html" xml:base="https://bec-systems.com/462/embedded-linux-versus-windows-ce/">&lt;p&gt;Occasionally I am asked how Embedded Linux compares with Windows CE.  I have spent the past 5 years doing mostly embedded Linux development, and the previous 5 years doing mostly WinCE development with a few exceptions, so my thoughts are no doubt a little biased toward what I understand best.  So take this with a grain of salt :-)  In my experience, the choice is often made largely on perception and culture, rather than concrete data.  And, making a choice based on concrete data is difficult when you consider the complexity of a modern OS, all the issues associated with porting it to custom hardware, and unknown future requirements.  Even from an application perspective, things change over the life of a project.  Requirements come and go.  You find yourself doing things you never thought you would, especially if they are possible.  The ubiquitous USB and network ports open a lot of possibilities – for example adding &lt;a href=&quot;&#x2F;tags&#x2F;cellular&#x2F;&quot;&gt;Cell modem support&lt;&#x2F;a&gt; or &lt;a href=&quot;&#x2F;218&#x2F;printing-from-embedded-systems&#x2F;&quot;&gt;printer support&lt;&#x2F;a&gt;. Flash based storage makes &lt;a href=&quot;&#x2F;146&#x2F;do-you-need-software-update&#x2F;&quot;&gt;in-field software updates&lt;&#x2F;a&gt; the standard mode of operation.  And in the end, each solution has its strengths and weaknesses – there is no magic bullet that is the best in all cases.&lt;&#x2F;p&gt;
&lt;p&gt;When considering Embedded Linux development, I often use the iceberg analogy; what you see going into a project is the part above the water.  These are the pieces your application interacts with, drivers you need to customize, the part you understand.  The other 90% is under water, and herein lies a great deal of variability.  Quality issues with drivers or not being able to find a driver for something you may want to support in the future can easily swamp known parts of the project.  There are very few people who have a lot of experience with both WinCE and Linux solutions, hence the tendency to go with what is comfortable (or what managers are comfortable with), or what we have experience with.  Below are thoughts on a number of aspects to consider:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;system-software-development&quot;&gt;SYSTEM SOFTWARE DEVELOPMENT&lt;&#x2F;h2&gt;
&lt;p&gt;Questions in this realm include CPU support, driver quality, in field software updates, filesystem support, driver availability, etc.  One of the changes that has happened in the past two years, is CPU vendors are now porting Linux to their new chips as the first OS.  Before, the OS porting was typically done by Linux software companies such as MontaVista, or community efforts.  As a result, the Linux kernel now supports most mainstream embedded cpus with few additional patches.  This is radically different than the situation 5 years ago.  Because many people are using the same source code, issues get fixed, and often are contributed back to the mainstream source.  With WinCE, the BSP&#x2F;driver support tends to be more of a reference implementation, and then OEM&#x2F;users take it, fix any issues, and that is where the fixes tend to stay.&lt;&#x2F;p&gt;
&lt;p&gt;From a system perspective, it is very important to consider flexibility for future needs.  Just because it is not a requirement now does not mean it will not be a requirement in the future.  Obtaining driver support for a peripheral may be nearly impossible, or be too large an effort to make it practical.&lt;&#x2F;p&gt;
&lt;p&gt;Most people give very little thought to the build system, or never look much beyond the thought that “if there is a nice gui wrapped around the tool, it must be easy”.  OpenEmbedded is very popular way to build embedded Linux products, and has recently been endorsed as the technology base of MontaVista’s Linux 6 product, and is generally considered “hard to use” by new users.  While WinCE build tools look simpler on the surface (the 10% above water), you still have the problem of what happens when I need to customize something, implement complex features such as software updates, etc.  To build a production system with production grade features, you still need someone on your team who understands the OS and can work at the detail level of both the operating system, and the build system.  With either WinCE or Embedded Linux, this generally means companies either need to have experienced developers in house, or hire experts to do portions of the system software development.  System software development is not the same as application development, and is generally not something you want to take on with no experience unless you have a lot of time.  It is quite common for companies to hire expert help for the first couple projects, and then do follow-on projects in-house.  Another feature to consider is parallel build support.  With quad core workstations becoming the standard, is it a big deal that a full build can be done in 1.2 hours versus 8?  How flexible is the build system at pulling and building source code from various sources such as diverse revision control systems, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Embedded processors are becoming increasingly complex.  It is no longer good enough to just have the cpu running.  If you consider the OMAP3 cpu family from TI, then you have to ask the following questions: are there libraries available for the 3D acceleration engine, and can I even get them without committing to millions of units per year?  Is there support for the DSP bridge?  What is the cost of all this?  On a recent project I was involved in, a basic WinCE BSP for the Atmel AT91SAM9260 cost $7000.  In terms of developer time, this is not much, but you have to also consider the on-going costs of maintenance, upgrading to new versions of the operating system, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;application-development&quot;&gt;APPLICATION DEVELOPMENT&lt;&#x2F;h2&gt;
&lt;p&gt;Both Embedded Linux and WinCE support a range of application libraries and programming languages.  C and C++ are well supported.  Most business type applications are moving to C# in the WinCE world.  Linux has Mono, which provides extensive support for .NET technologies and runs very well in embedded Linux systems.  There are numerous Java development environments available for Embedded Linux.  One area where you do run into differences is graphics libraries.  Generally the Microsoft graphical APIs are not well supported on Linux, so if you have a large application team that are die-hard windows GUI programmers, then perhaps WinCE makes sense.  However, there are many options for GUI toolkits that run on both Windows PCs and Embedded Linux devices.  Some examples include GTK+, Qt, wxWidgets, etc.  The Gimp is an example of a GTK+ application that runs on windows, plus there are many others.  The are C# bindings to GTK+ and Qt.  Another feature that seems to be coming on strong in the WinCE space is the Windows Communication Foundation (WCF).  But again, there are projects to bring WCF to Mono, depending what portions you need.  Embedded Linux support for scripting languages like Python is very good, and Python runs very well on 200MHz ARM processors.&lt;&#x2F;p&gt;
&lt;p&gt;There is often the perception that WinCE is realtime, and Linux is not.  Linux realtime support is decent in the stock kernels with the CONFIG_PREEMPT option, and real-time support is excellent with the addition of a relatively small &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;rt.wiki.kernel.org&#x2F;index.php&#x2F;Main_Page&quot;&gt;real-time patch&lt;&#x2F;a&gt;.  You can easily attain sub millisecond timing with Linux.  This is something that has changed in the past couple years with the merging of real-time functionality into the stock kernel.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;development-flow&quot;&gt;DEVELOPMENT FLOW&lt;&#x2F;h2&gt;
&lt;p&gt;In a productive environment, most advanced embedded applications are developed and debugged on a PC, not the target hardware.  Even in setups where remote debugging on a target system works well, debugging an application on a workstation works better.  So the fact that one solution has nice on-target debugging, where the other does not is not really relevant.  For data centric systems, it is common to have simulation modes where the application can be tested without connection to real I&#x2F;O.  With both Linux and WinCE applications, application programing for an embedded device is similar to programming for a PC.  Embedded Linux takes this a step further.  Because embedded Linux technology is the same as desktop, and server Linux technology, almost everything developed for desktop&#x2F;server (including system software) is available for embedded for free.  This means very complete driver support (see USB cell modem and printer examples above), robust file system support, memory management, etc.  The breadth of options for Linux is astounding, but some may consider this a negative point, and would prefer a more integrated solution like Windows CE where everything comes from one place.  There is a loss of flexibility, but in some cases, the tradeoff might be worth it.  For an example of the number of packages that can be build for Embedded Linux systems using Openembedded, see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gui-trends&quot;&gt;GUI TRENDS&lt;&#x2F;h2&gt;
&lt;p&gt;It is important to consider trends for embedded devices with small displays being driven by Cell Phones (iPhone, Palm Pre, etc).  Standard GUI widgets that are common in desktop systems (dialog boxes, check boxes, pull down lists, etc) do not cut it for modern embedded systems.  So, it will be important to consider support for 3D effects, and widget libraries designed to be used by touch screen devices.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.clutter-project.org&#x2F;&quot;&gt;Clutter library&lt;&#x2F;a&gt; is an example of this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remote-support&quot;&gt;REMOTE SUPPORT&lt;&#x2F;h2&gt;
&lt;p&gt;Going back to the issue of debugging tools, most people stop at the scenario where the device is setting next to a workstation in the lab.  But what about when you need to troubleshoot a device that is being beta-tested half-way around the world?  That is where a command-line debugger like Gdb is an advantage, and not a disadvantage.  And how do you connect to the device if you don’t have support for cell modems in New Zealand, or an efficient connection mechanism like ssh for shell access and transferring files?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;SUMMARY&lt;&#x2F;h2&gt;
&lt;p&gt;Selecting any advanced technology is not a simple task, and is fairly difficult to do even with experience.  So it is important to be asking the right questions, and looking at the decision from many angles.  Hopefully this article can help in that.  For additional assistance, please do not hesitate to &lt;a href=&quot;&#x2F;#work-together&quot;&gt;contact BEC Systems&lt;&#x2F;a&gt; – we’re here to help.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dealing with large data structures efficiently in embedded systems</title>
        <published>2009-05-26T00:00:00+00:00</published>
        <updated>2009-05-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/438/dealing-with-large-data-structures-efficiently-in-embedded-systems/"/>
        <id>https://bec-systems.com/438/dealing-with-large-data-structures-efficiently-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/438/dealing-with-large-data-structures-efficiently-in-embedded-systems/">&lt;p&gt;I’m currently dealing with a programming problem where I need access to several 64MB, file-backed data structures concurrently on an Embedded Linux system that only has 64MB of RAM.  The data structures are fairly sparse (mostly zero data), and I typically only need to access small portions of them at any particular time.  There is always the brute-force approach where you write code to manually load sections of the file as you need them.  But with a little thought, the realisation hits “this is what operating systems do.”  This article explores using memory mapping, and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sparse_file&quot;&gt;sparse file&lt;&#x2F;a&gt; support in file systems to solve this problem in a very efficient manner.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sparse-file-support&quot;&gt;Sparse File Support&lt;&#x2F;h2&gt;
&lt;p&gt;Most Unix file systems support &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sparse_file&quot;&gt;sparse files&lt;&#x2F;a&gt;.  This means that sections of data that is zeros is not stored on the disk.  Consider the following example where we create a 200MB file that is all zeros:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# df
Filesystem           1k-blocks      Used Available Use% Mounted on
&#x2F;dev&#x2F;mmcblk0p1         3917212    202448   3515776   5% &#x2F;media&#x2F;mmcblk0p1

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# dd if=&#x2F;dev&#x2F;zero of=sparse-file bs=1 \
count=1 seek=200M

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# df
Filesystem           1k-blocks      Used Available Use% Mounted on
&#x2F;dev&#x2F;mmcblk0p1         3917212    202456   3515768   5% &#x2F;media&#x2F;mmcblk0p1

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# ls -l
-rw-r--r--    1 root     root    209715201 May 22 08:54 sparse-file

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time od sparse-file
0000000  000000 000000 000000 000000 000000 000000 000000 000000
*
1440000000
real    0m 17.23s
user    0m 14.21s
sys     0m 2.66s

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# du sparse-file
68      sparse-file
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It this case we created a 200MiB file on a SD card formatted as ext3.  Even though the file is 200M in size, it only uses a few KiB of disk space.  This same test also worked fine with a JFFS2 filesystem.  With sparse file support, we get a cheap form of run length compression (at least for zeros) with no effort.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mmap&quot;&gt;mmap()&lt;&#x2F;h2&gt;
&lt;p&gt;The mmap() system call is used to map a file, or portions of a file into memory.  The data in the file can then be accessed directly in memory.  Because Linux is a demand paged system, portions of the file are paged in as needed, so the entire file does not need to be present in RAM at one time.  There are several advantages to using mmap():&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;mmap() avoids the extraneous copy that occurs when using read() or write() as the data does not need to be copied to a user space buffer.&lt;&#x2F;li&gt;
&lt;li&gt;there is very little overhead&lt;&#x2F;li&gt;
&lt;li&gt;you can directly access any part of the file without doing a lseek() and keeping track of where you are.&lt;&#x2F;li&gt;
&lt;li&gt;the operating system takes care of paging in sections of the file you are using, and discarding sections that are not in use when memory is low.  This includes flushing dirty portions to disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;What this means, is mmap gives you an easy way to work on large, file backed data structures, and the OS takes care of loading the portions you need, and saving the modified portions back to disk.  As most embedded systems are 32-bit, there is a limit to the file size you can use as virtual memory space is limited.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-application&quot;&gt;Test Application&lt;&#x2F;h2&gt;
&lt;p&gt;Next I wrote a small application that is used to create, and modify files using mmap().  I wanted to experiment with creating files of various sizes, writing non-zero data at various intervals, and test the performance of this.  The test application source is located &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;sparse_file_mmap_test&#x2F;sparse_file_mmap_test.c&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Usage: sparse_file_mmap_test [OPTION]

-s, --filesize   File size to allocate
  -o, --offset     Will write a few bytes every offset bytes
  -m, --modify     Modify existing file
  -d, --data       Data to write to file at offset location (0-255)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The application creates a file of size &lt;em&gt;filesize&lt;&#x2F;em&gt;, and writes the value of &lt;em&gt;data&lt;&#x2F;em&gt; to the file every &lt;em&gt;offset&lt;&#x2F;em&gt; bytes.  There is also an option to modify existing files, so we can test the performance of opening a large file, making a small change, and then closing it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-results&quot;&gt;Test Results&lt;&#x2F;h2&gt;
&lt;p&gt;The results are pretty amazing, and the performance is beyond my expectations. This type of problem is where you learn to appreciate the performance of an advanced operating system, and file system.  There is a reason for the complexity!  There are 3 things I wanted to test: 1) does the sparse file support work as expected? 2) can mmap be used to easily modify large files? 3) can mmap be used to work on data structures that are larger than physical RAM?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-sparse-file-support&quot;&gt;1. Sparse File Support&lt;&#x2F;h2&gt;
&lt;p&gt;The basic tests above confirm that sparse file support works for an empty file, but what about a file that has some data every X bytes?  Below are the test results for creating a 10MB file, and writing data at various offset intervals.&lt;&#x2F;p&gt;
&lt;table border=&quot;0&quot; cellspacing=&quot;0&quot; frame=&quot;void&quot; rules=&quot;none&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width=&quot;93&quot; height=&quot;17&quot; align=&quot;left&quot;&gt;&lt;strong&gt;Offset (bytes)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td width=&quot;94&quot; align=&quot;left&quot;&gt;&lt;strong&gt;File Size (KB)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;1024&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;9784&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;2048&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;9784&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;4096&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;9784&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;8192&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;4904&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;16384&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;2464&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;32768&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;1244&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;65536&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;632&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;1048576&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;60&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;2097152&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;40&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;4194304&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;32&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;As soon as the offset was greater than the MMU page size (4KB), then the sparse file effect started to kick in and worked as expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-can-mmap-be-used-to-efficiently-modify-large-files&quot;&gt;2. Can mmap() be used to efficiently modify large files?&lt;&#x2F;h2&gt;
&lt;p&gt;The test here was to open a large file, make a small change in the middle, and then close it.  In this case a 100MB file was created with a data value of 1 written every 1MB, and then re-opened the same file and wrote a data value of 2 every 2MB.  The od utility was used to examine the file to verify the contents were correct.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time sparse_file_mmap_test_arm -s104857600 \
-o1048576 -d1
Sparse File mmap() test
Filesize = 104857600, offset = 1048576, data = 1
size = 102400 KB
size on disk (KB):
508     sparse-file
real    0m 1.10s
user    0m 0.00s
sys     0m 0.43s

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time sparse_file_mmap_test_arm -s104857600 \
-o2097152 -d2 -m
Sparse File mmap() test
Filesize = 104857600, offset = 2097152, data = 2
size = 102400 KB
size on disk (KB):
508     sparse-file
real    0m 0.37s
user    0m 0.01s
sys     0m 0.05s

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time od -x sparse-file
0000000     0002    0000    0000    0000    0000    0000    0000    0000
0000020     0000    0000    0000    0000    0000    0000    0000    0000
*
4000000     0001    0000    0000    0000    0000    0000    0000    0000
4000020     0000    0000    0000    0000    0000    0000    0000    0000

....
*
614000000     0001    0000    0000    0000    0000    0000    0000    0000
614000020     0000    0000    0000    0000    0000    0000    0000    0000
*
620000000
real    0m 12.93s
user    0m 7.33s
sys     0m 1.70s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creating and modifying large file-backed data structures is very fast and efficient, and takes on the order of 1 second for a 100MB file that contains data every 1MB.  Dumping the data with od took considerably longer (13 seconds) as 100MB of data needed to be processed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;possible-issues&quot;&gt;Possible Issues&lt;&#x2F;h2&gt;
&lt;p&gt;There are several things to watch out for when using sparse files and mmap()&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;With sparse files, there is the potential to run out of disk space as the files are using less space on disk than the file size.  It is a good idea to monitor disk space when working with sparse files, so you don’t use up all of the disk space.&lt;&#x2F;li&gt;
&lt;li&gt;mmap() requires virtual memory space for the size file it maps.  With embedded systems, this is less of an issue, because the physical RAM size tends to be much less than the 4GB virtual address space.  With a system that only has 64MB of RAM, mmap()’ing files in the 10’s of MB in size makes a lot of sense because it insures that you will not run the system out of memory, and yet there should be plenty of virtual address space to map in files of this size.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;mmap() and sparse file support provide a very convenient solution for dealing with large, file-backed data structures.  One example of this type of data structure is any type of large matrix such as maps used in mapping applications.  Writing a “from scratch” solution to solve this problem would be a fairly large and difficult task.  Processing large amounts of data efficiently is becoming more and more important in many embedded systems. This example provides another compelling reason why implementing modern, data-centric embedded systems using Linux makes a lot of sense.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MontaVista Linux 6 is based on OpenEmbedded Technologies</title>
        <published>2009-05-13T00:00:00+00:00</published>
        <updated>2009-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/425/montavista-linux-6-is-based-on-openembedded-technologies/"/>
        <id>https://bec-systems.com/425/montavista-linux-6-is-based-on-openembedded-technologies/</id>
        
        <content type="html" xml:base="https://bec-systems.com/425/montavista-linux-6-is-based-on-openembedded-technologies/">&lt;p&gt;Very interesting news from MontaVista yesterday as they announced &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mvista.com&#x2F;product_detail_mvl6.phphttp:&#x2F;&#x2F;mvista.com&#x2F;product_detail_mvl6.php&quot;&gt;MontaVista Linux 6&lt;&#x2F;a&gt;.  It turns out they are using bitbake, which is the core of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&quot;&gt;OpenEmbedded&lt;&#x2F;a&gt; build system.  Along with the adoption of OpenEmbedded in many leading Embedded Linux efforts (Beagleboard, Gumstix, Bug Labs, etc), this is a resounding affirmation that the OpenEmbedded way of building distributions is worthy of consideration.  It is a well known fact that OpenEmbedded has some deficiencies: a steep learning curve, the testing&#x2F;quality efforts could be improved, and the organisational aspects of the project are somewhat lacking.  That said, OpenEmbedded is still the most effective tool for building Embedded Linux distributions that I’ve found yet, and is a very viable solution if you are willing to spend some time to learn it, or hire a consultant to get your project set up and work through the rough spots.  MontaVista is attempting to address these difficulties with their MVL6 commercial offering.&lt;&#x2F;p&gt;
&lt;p&gt;Below are few a notes from watching a few videos on the MV web site:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mvista.com&#x2F;download&#x2F;playvideo.php?v=Discussion_with_Jim_Ready&quot;&gt;Discussion with Jim Ready&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;around 2006 things changed&lt;&#x2F;li&gt;
&lt;li&gt;Semiconductor vendors now porting Linux to all their CPUs, so MV has moved up the stack&lt;&#x2F;li&gt;
&lt;li&gt;MVL6 first embedded linux distro produced in post-victory phase (Linux has won)&lt;&#x2F;li&gt;
&lt;li&gt;very friendly with other open source pieces (I assume OpenEmbedded)&lt;&#x2F;li&gt;
&lt;li&gt;enable open source&lt;&#x2F;li&gt;
&lt;li&gt;The decision the use Linux is the right decision technically.  What is the right business decision to accompany the technical decision?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mvista.com&#x2F;download&#x2F;playvideo.php?v=MVL6_Demonstration&quot;&gt;MVL6 Demonstration&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;toolchains pre-packaged&lt;&#x2F;li&gt;
&lt;li&gt;sources are all downloaded from MV servers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mvista.com&#x2F;download&#x2F;playvideo.php?v=Interview_with_Joe_Green&quot;&gt;Interview with Joe Green&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;manager of developer tools team&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MLV6 is new approach&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;previous editions were consistent for all targets&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MLV6 more flexible model.  Market specific distros depending on market.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;source driven product.  Previous products based on binary RPMs.  MLV6 is a lot easier to build the whole environment.  Very customized&#x2F;fine-tuned distro.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;key problems MLV6 solves&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Complete starting point for target hardware&lt;&#x2F;li&gt;
&lt;li&gt;complete build system, so you have total control vs pre-canned distribution that sets all the rules&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Integration platform based on Bitbake.  Working closely with community.  Enhanced in a number of ways.  Customers have the option of bringing in software developed by the OpenEmbedded community and bringing it into their project.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Gives you a system that you can configure at almost any level.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Enhancements to make it easy to make changes, as well as provide a pre-built starting point.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Features to control sources, and environment so the host environment does not contaminate your build.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Essentially hardening, and commercializing the bitbake and openembedded projects.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Why MVL6 vs roll-your-own.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Qualified starting point&lt;&#x2F;li&gt;
&lt;li&gt;Support.  Community or Semi-conductor vendor support is hit or miss.&lt;&#x2F;li&gt;
&lt;li&gt;Consistent environment accross multiple systems.&lt;&#x2F;li&gt;
&lt;li&gt;Includes devrocket graphical tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Overall, this seems like a very good approach.  I’m glad they are not re-inventing the wheel, but instead have chosen to build on top of a proven open source solution, and leverage the work that is being done by a very active community of OpenEmbedded developers.  The OpenEmbedded project currently has 61 developers (not all are active), and weekly contribution rate is very good.  This type of effort would be very difficult to match by any but the largest commercial organizations.  This should be a win-win situation for all involved.  As a common base technology, the Bitbake and OpenEmbedded projects should improve due to MV’s involvement.  Through the MVL6 product, the OpenEmbedded project and way of doing things will get a lot more exposure and there will be a lot more developers who understand how it works.  Developers who are familiar with the OpenEmbedded build system will be able to apply their knowlege to a greater number of projects.   And developers building products will have more options for getting the support and techology they need.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to set up a NFS root filesystem for embedded Linux development</title>
        <published>2009-05-11T00:00:00+00:00</published>
        <updated>2009-05-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/418/how-to-set-up-a-nfs-rootfs/"/>
        <id>https://bec-systems.com/418/how-to-set-up-a-nfs-rootfs/</id>
        
        <content type="html" xml:base="https://bec-systems.com/418/how-to-set-up-a-nfs-rootfs/">&lt;p&gt;Although ssh and friends work really well for embedded systems, occasionally you want to set up a NFS root for development.  One of the scenarios where nfsroot is useful is if you are making a lot of rootfs changes, and you don’t want to spend the time to reprogram the flash on the target system.  Fortunately, the Linux kernel includes complete support for NFS root, and does not require any userspace changes.  This setup assumes the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;the target system has Ethernet support built into the kernel&lt;&#x2F;li&gt;
&lt;li&gt;the target system is on the same network as a Linux workstation&lt;&#x2F;li&gt;
&lt;li&gt;said network includes a DHCP server&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This configuration emphasises “simple” and does not require you to spend 4 hours trying to get a bootp server configured on a test network.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kernel-support&quot;&gt;Kernel Support&lt;&#x2F;h2&gt;
&lt;p&gt;Make sure you have the following options turned on in the kernel:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CONFIG_IP_PNP_DHCP=y&lt;&#x2F;li&gt;
&lt;li&gt;CONFIG_ROOT_NFS=y&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Then, add the following to your kernel CMDLINE:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;ip=dhcp root=&#x2F;dev&#x2F;nfs nfsroot=&amp;lt;nfs server IP&amp;gt;:&#x2F;path&#x2F;to&#x2F;nfsroot
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;workstation-setup&quot;&gt;Workstation Setup&lt;&#x2F;h2&gt;
&lt;p&gt;The following setup is for Ubuntu.&lt;&#x2F;p&gt;
&lt;p&gt;apt-get install nfs-user-server&lt;&#x2F;p&gt;
&lt;p&gt;(edit &#x2F;etc&#x2F;exports to contain something like the following)&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;path&#x2F;to&#x2F;nfsroot 192.168.1.0&#x2F;255.255.255.0(no_root_squash,sync,rw)&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;init.d&#x2F;nfs-user-server restart&lt;&#x2F;p&gt;
&lt;p&gt;If you are using OpenEmbedded, then instruct OE to generate a rootfs tar image, and extract to your nfsroot directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cd &#x2F;path&#x2F;to&#x2F;nfsroot
sudo tar -xvf &amp;lt;path to OE images dir&amp;gt;&#x2F;Angstrom-image...rootfs.tar
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;and-the-result&quot;&gt;And the result&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
Sending DHCP requests ., OK
IP-Config: Got DHCP answer from 192.168.1.1, my address is 192.168.1.112
IP-Config: Complete:
     device=eth0, addr=192.168.1.112, mask=255.255.255.0, gw=192.168.1.1,
     host=192.168.1.112, domain=hq.bec-systems.com, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.11, rootpath=
Looking up port of RPC 100003&#x2F;2 on 192.168.1.11
Looking up port of RPC 100005&#x2F;1 on 192.168.1.11
VFS: Mounted root (nfs filesystem) readonly.
Freeing unused kernel memory: 220k freed
Write protecting the kernel text: 2792k
Write protecting the kernel read-only data: 788k
INIT: version 2.86 booting
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 kernel updated to 2.6.29 in OE</title>
        <published>2009-04-24T00:00:00+00:00</published>
        <updated>2009-04-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/413/compulab-cm-x270-kernel-updated-to-2629-in-oe/"/>
        <id>https://bec-systems.com/413/compulab-cm-x270-kernel-updated-to-2629-in-oe/</id>
        
        <content type="html" xml:base="https://bec-systems.com/413/compulab-cm-x270-kernel-updated-to-2629-in-oe/">&lt;p&gt;The cm-x270 kernel support in OpenEmbedded has just been &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;commit&#x2F;&amp;amp;id=23ac197703f9cc49e7a69ea34e24e4c885e485a1&quot;&gt;updated&lt;&#x2F;a&gt; to version 2.6.29.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wi2Wi W2CBW003 Wifi&#x2F;Bluetooth module review</title>
        <published>2009-03-19T00:00:00+00:00</published>
        <updated>2009-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/387/wi2wi-wifi-bt-module-review/"/>
        <id>https://bec-systems.com/387/wi2wi-wifi-bt-module-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/387/wi2wi-wifi-bt-module-review/">&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.wi2wi.com&#x2F;wireless.php&quot;&gt;Wi2Wi W2CBW003&lt;&#x2F;a&gt; is a highly integrated module that provides both Wifi and Bluetooth radios for embedded designs.  This module is ideal for embedded designs, as it provides a lot of functionality in a small package and includes standard interfaces like SPI, SDIO and serial that connect with most embedded CPUs.  With the availability of modules like the W2CBW003 and standard drivers in the Linux kernel, including radio functionality in an embedded device is very doable, even for low volume products.  Wi2Wi provides an evaluation board for the W2CBW003 with a SDIO connector, UART connector, and BT Audio Connectors.  For this review, the eval board was connected to a Marvel PXA270 ARM processor, and evaluated with current Linux and associated software.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;w2cbw003-overview&quot;&gt;W2CBW003 Overview&lt;&#x2F;h2&gt;
&lt;p&gt;The W2CBW003 module integrates both WiFi and Bluetooth functionality in a 12mm x 12mm x 1.6mm package.   The WiFi portion is based on the Marvell 88W8686, and the Bluetooth on the CSR BC04.  Both of these components are well supported by Open Source software.  Some other features include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Separate Antennas for WiFi and BT.&lt;&#x2F;li&gt;
&lt;li&gt;ROHS compliant&lt;&#x2F;li&gt;
&lt;li&gt;Single Supply at 3.3V&lt;&#x2F;li&gt;
&lt;li&gt;802.11g support (54Mbps)&lt;&#x2F;li&gt;
&lt;li&gt;Both SPI and SDIO interfaces for WiFi&lt;&#x2F;li&gt;
&lt;li&gt;UART interface for BT&lt;&#x2F;li&gt;
&lt;li&gt;PCM audio interface for BT&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Pictures of the module and the demo board are shown below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;03&#x2F;img_1798_small-1.jpg&quot; alt=&quot;img_1798_small&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;03&#x2F;img_1800_small-1.jpg&quot; alt=&quot;img_1800_small&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;evaluation-system-configuration&quot;&gt;Evaluation System Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;The test software included with the Wi2Wi eval board is for a Windows PC, is provided in binary format only, and was not used in this review.  For this review, I plugged the W2CBW003 demo board into a Compulab cm-x270 board (PXA270 cpu) running a 2.6.29-rc7 Linux kernel and a recent OpenEmbedded Angstrom distribution.   With the exception of the Marvell Wifi Firmware, all software in this setup is Open Source and is available in the Linux kernel, and as packages in the OpenEmbedded Project.&lt;&#x2F;p&gt;
&lt;p&gt;When booting the kernel, you will see the following messages:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mmc0: new SDIO card at address 0001
libertas_sdio mmc0:0001:1: firmware: requesting sd8686_helper.bin
libertas_sdio mmc0:0001:1: firmware: requesting sd8686.bin
libertas: 00:19:88:06:0b:2e, fw 9.70.3p25, cap 0x00000303
eth2 (libertas_sdio): not using net_device_ops yet
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: eth2: Marvell WLAN 802.11 adapter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The “command 0x00a3 failed” messages are harmless, and have to do with features that are not supported.  After the system boots, you will now see a new ethX network device:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# ifconfig -a
...
eth2      Link encap:Ethernet  HWaddr 00:19:88:06:0B:2E
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:65902 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1758 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:13550002 (12.9 MiB)  TX bytes:251627 (245.7 KiB)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The “&lt;em&gt;iwlist eth2 scanning&lt;&#x2F;em&gt;” command will list available access points.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;connecting-to-open-wifi-networks&quot;&gt;Connecting to Open WiFi Networks&lt;&#x2F;h2&gt;
&lt;p&gt;A connection to an open wifi network can be accomplished by placing the following in &#x2F;etc&#x2F;network&#x2F;interfaces:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;etc&#x2F;network&#x2F;interfaces:
iface eth1 inet dhcp
    wireless_mode managed
    wireless_essid any
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now execute “ifup eth2”:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# ifup eth2
udhcpc (v1.13.2) started
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
Sending discover...
Sending select for 192.168.1.115...
Lease of 192.168.1.115 obtained, lease time 86400
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
adding dns 208.67.222.222
adding dns 208.67.220.220

root@cm-x270:~# iwlist eth2
iwlist: unknown command `eth2&amp;#39; (check &amp;#39;iwlist --help&amp;#39;).
root@cm-x270:~# iwconfig eth2
eth2      IEEE 802.11b&#x2F;g  ESSID:&amp;quot;bec3&amp;quot;
          Mode:Managed  Frequency:2.437 GHz  Access Point: 00:18:39:C1:AD:4A
          Bit Rate:1 Mb&#x2F;s   Tx-Power=13 dBm
          Retry short limit:8   RTS thr=2347 B   Fragment thr=2346 B
          Encryption key:off
          Power Management:off
          Link Quality=84&#x2F;100  Signal level=-37 dBm  Noise level=-87 dBm
          Rx invalid nwid:0  Rx invalid crypt:14707457  Rx invalid frag:0
          Tx excessive retries:58  Invalid misc:3   Missed beacon:0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;wpa-secured-wifi-networks&quot;&gt;WPA Secured WiFi Networks&lt;&#x2F;h2&gt;
&lt;p&gt;The OpenEmbedded console image includes the WPA Supplicant packages which is used to manage wireless connections to secured networks.  To set up the system for WPA encryption, modify the following files:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;etc&#x2F;network&#x2F;interfaces:
iface eth2 inet dhcp
   wpa-conf &#x2F;etc&#x2F;wpa_supplicant&#x2F;wpa_supplicant.conf
   wpa-driver wext
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;etc&#x2F;wpa_supplicant&#x2F;wpa_supplicant.conf:
ctrl_interface=&#x2F;var&#x2F;run&#x2F;wpa_supplicant
ctrl_interface_group=0
eapol_version=1
ap_scan=1
fast_reauth=1

network={
      ssid=&amp;quot;bec&amp;quot;
      proto=WPA2
      key_mgmt=WPA-PSK
      pairwise=CCMP TKIP
      group=CCMP TKIP
      scan_ssid=1
      psk=&amp;quot;ascii passphrase&amp;quot;
      priority=10
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, execute “ifup eth2”, and you should see something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# ifup eth2
WPA: Configuring Interface
udhcpc (v1.13.2) started
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
Sending discover...
Sending select for 192.168.1.115...
Lease of 192.168.1.115 obtained, lease time 86400
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
adding dns 208.67.222.222
adding dns 208.67.220.220
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# iwconfig eth2
eth2      IEEE 802.11b&#x2F;g  ESSID:&amp;quot;bec&amp;quot;
          Mode:Managed  Frequency:2.412 GHz  Access Point: 00:40:10:10:00:03
          Bit Rate:1 Mb&#x2F;s   Tx-Power=13 dBm
          Retry short limit:8   RTS thr=2347 B   Fragment thr=2346 B
          Encryption key:&amp;lt;too big&amp;gt;   Security mode:open
          Power Management:off
          Link Quality=64&#x2F;100  Signal level=-68 dBm  Noise level=-89 dBm
          Rx invalid nwid:0  Rx invalid crypt:-1463809279  Rx invalid frag:0
          Tx excessive retries:22524  Invalid misc:3   Missed beacon:0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;other-observations&quot;&gt;Other Observations&lt;&#x2F;h2&gt;
&lt;p&gt;With the above networks, the &lt;em&gt;bec&lt;&#x2F;em&gt; access point was much further away than the &lt;em&gt;bec3&lt;&#x2F;em&gt;AP, so you will notice the difference in link quality.  “&lt;em&gt;iwlist eth2 rate&lt;&#x2F;em&gt;” can be used to list the current connection rate.  When the network is idle, it sits at 1Mb&#x2F;s.  When downloading a large file, it will climb to 36 or 54Mb&#x2F;s, depending on link quality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;production-issues&quot;&gt;Production Issues&lt;&#x2F;h2&gt;
&lt;p&gt;The review demonstrates that it is fairly simple to set up a demo quality Embedded Linux system with WiFi.  Some of the issues that would likely need addressed for a production system include link management, test software for certification, and power management.&lt;&#x2F;p&gt;
&lt;p&gt;There are several ways to programatically control WPA Supplicant including linking to the wpa supplicant control interface, or using DBus.  There are several WiFi management applications available including &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;projects.gnome.org&#x2F;NetworkManager&#x2F;&quot;&gt;Gnome NetworkManager&lt;&#x2F;a&gt; (used in desktop systems), and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;v1.moblin.org&#x2F;projects&#x2F;projects_connman.php&quot;&gt;connman&lt;&#x2F;a&gt; which seems a little better suited for embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Unless you use a completely pre-certified module + antenna solution, you will likely need to do some level of agency certification.  As many products use a custom antenna, this is an important issue to consider and plan for.  While Marvell provides test software and firmware, it will likely require some work, as their software is designed to be used with their in-house drivers rather than the libertas driver which is available  with modern kernels.&lt;&#x2F;p&gt;
&lt;p&gt;Also, if you want to minimize the power usage, some work will be required to figure out the power modes supported, and how to implement&#x2F;control them.  With this module, the Wifi and BT portions run off the same crystal, so if you only want the BT active, you will need to actively power manage the Wifi portion to a low power state instead of completely disabling it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;TheW2CBW003 module is an attractive solution for products that need WiFi functionality.  With the availability of modules like this, and mainstream open source software, the technology is available to about anyone, including low volume manufacturers.  Standard interfaces such as SDIO make it possible to interface this module with about any modern ARM processor that can run Linux.  Software support in the Linux kernel, wpa supplicant, and the Linux wireless tools provide the needed software support to implement a very complex system with relatively little effort.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Memory Performance on various Embedded Systems</title>
        <published>2009-03-04T00:00:00+00:00</published>
        <updated>2009-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/380/memory-performance-on-various-embedded-systems/"/>
        <id>https://bec-systems.com/380/memory-performance-on-various-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/380/memory-performance-on-various-embedded-systems/">&lt;p&gt;Marcin just published an interesting &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;marcin.juszkiewicz.com.pl&#x2F;2009&#x2F;02&#x2F;20&#x2F;does-vortex86sx-based-devices-are-worth-something&#x2F;&quot;&gt;article&lt;&#x2F;a&gt; about memory performance on various embedded systems using the hdparm -T as a simple benchmarq.  This test gives a pretty good indicator of memory performance in the system.  From the hdparm man page:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Perform timings of cache reads for benchmark and comparison purposes.  For meaningful results, this operation should be repeated 2-3  times on an otherwise inactive system (no other active processes) with at least a couple of megabytes of free memory.  This displays the speed of reading directly from the Linux buffer cache without disk access.  This measurement is essentially an indication of the throughput  of  the processor, cache, and memory of the system under test.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A few results I find interesting:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;modern desktop systems have an order of magnitude more memory bandwidth than ARM systems.&lt;&#x2F;li&gt;
&lt;li&gt;the i.MX31 is the highest performing ARM device tested&lt;&#x2F;li&gt;
&lt;li&gt;the i.MX31 performs better than the OMAP3 in this test – why is this?  As the ratio is 2, I’m guessing the bus is twice as wide?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Who is using OpenEmbedded?</title>
        <published>2009-02-20T00:00:00+00:00</published>
        <updated>2009-02-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/372/who-is-using-openembedded/"/>
        <id>https://bec-systems.com/372/who-is-using-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/372/who-is-using-openembedded/">&lt;p&gt;Having used OpenEmbedded for a number of Embedded Linux projects over the past 5 years, it is interesting watching new users come on board.  The most recent &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;thread.gmane.org&#x2F;gmane.comp.handhelds.openembedded&#x2F;21188&quot;&gt;announcement came from Koan&lt;&#x2F;a&gt; that the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.kaeilos.com&#x2F;&quot;&gt;KaeilOS&lt;&#x2F;a&gt; distribution will be joining the OpenEmbedded project.  In the announcement, they summed up my thoughts well:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;We at KOAN wanted to avoid waste of energy converging KOAN efforts into a stable and solid Open Source project like OE is.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;“Avoid waste of energy” – isn’t this what OSS is all about?  Life is way too short to re-invent every wheel.  Considering OpenEmbedded has dozens of active contributors, it would be very difficult for any one company to replicate the functionality of OpenEmbedded. Although there are many ways to build embedded Linux distributions, and some tools do some things better than OE, there still does not seem to be any other embedded Linux build tool that fulfills the following requirements as well as OE:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;build from scratch on any x86 Linux system&lt;&#x2F;li&gt;
&lt;li&gt;large number of contributors&lt;&#x2F;li&gt;
&lt;li&gt;large number of packages&lt;&#x2F;li&gt;
&lt;li&gt;support a large number of architectures&lt;&#x2F;li&gt;
&lt;li&gt;Can modify images and integrate custom applications in a consistent way as part of the build system, and not a post processing hack.&lt;&#x2F;li&gt;
&lt;li&gt;Open Source&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Some other companies using OpenEmbedded include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;TI&lt;&#x2F;li&gt;
&lt;li&gt;AMD&lt;&#x2F;li&gt;
&lt;li&gt;Intel (was OpenedHand)&lt;&#x2F;li&gt;
&lt;li&gt;Gumstix&lt;&#x2F;li&gt;
&lt;li&gt;Bug Labs&lt;&#x2F;li&gt;
&lt;li&gt;OpenMoko&lt;&#x2F;li&gt;
&lt;li&gt;Atmel&lt;&#x2F;li&gt;
&lt;li&gt;Techsol&lt;&#x2F;li&gt;
&lt;li&gt;Compulab&lt;&#x2F;li&gt;
&lt;li&gt;Toradex&lt;&#x2F;li&gt;
&lt;li&gt;4G-Systems&lt;&#x2F;li&gt;
&lt;li&gt;Dream Multimedia TV&lt;&#x2F;li&gt;
&lt;li&gt;M&amp;amp;N Solutions&lt;&#x2F;li&gt;
&lt;li&gt;emQbit&lt;&#x2F;li&gt;
&lt;li&gt;Siemens&lt;&#x2F;li&gt;
&lt;li&gt;Embedded Alley&lt;&#x2F;li&gt;
&lt;li&gt;and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;SuccessStories&quot;&gt;list goes on&lt;&#x2F;a&gt; …. (If you are using OpenEmbedded, please add your name to this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;SuccessStories&quot;&gt;list&lt;&#x2F;a&gt;.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’m looking forward to seeing the KaeilOS improvements such as mdev, and boot time improvements.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sprint 598U USB Broadband Modem in Embedded Systems</title>
        <published>2009-02-07T00:00:00+00:00</published>
        <updated>2009-02-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/353/sprint-598u-usb-broadband-modem-in-embedded-systems/"/>
        <id>https://bec-systems.com/353/sprint-598u-usb-broadband-modem-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/353/sprint-598u-usb-broadband-modem-in-embedded-systems/">&lt;p&gt;One thing that works really well in Linux is support for USB Broadband modems.  While it usually takes a little fiddling with PPP scripts, it is generally not too difficult to get working.  One of the reasons for this is most modems implement a USB serial interface, and then the modem is controlled with standard AT commands.  A customer who currently supports a &lt;a href=&quot;&#x2F;203&#x2F;using-a-verizon-usb720-modem-in-an-embedded-linux-system&#x2F;&quot;&gt;Verizon USB modem&lt;&#x2F;a&gt; in their product wanted to add support for a Sprint modem.  After a little research, we settled on the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.sierrawireless.com&#x2F;product&#x2F;USB598.aspx&quot;&gt;598U from Sierra Wireless&lt;&#x2F;a&gt;.  Below is a picture of the 598U plugged into an industrial terminal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;02&#x2F;img_17721-1.jpg&quot; alt=&quot;sprint 598U modem&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-are-usb-broadband-modems-useful-in-embedded-systems&quot;&gt;Why are USB Broadband modems useful in Embedded Systems?&lt;&#x2F;h2&gt;
&lt;p&gt;As systems become more complex, and time to market is shrinking (thus less testing), it is becoming increasingly important to be able to remotely diagnose problems.  With a broadband modem like the Sprint 598U, developers can remotely log into a device using SSH, and debug problems.  This is a huge benefit.  The cost of the modem and a 1 year data plan becomes fairly insignificant when you consider the cost to fly a developer on-site to debug issues.  While there are other ways to remotely access an embedded system, such as &lt;a href=&quot;&#x2F;137&#x2F;remote-access-for-embedded-systems-behind-a-firewall&#x2F;&quot;&gt;reverse ssh&lt;&#x2F;a&gt;, the simplicity of the broadband modem is attractive as it bypasses the firewall issues.  Even with reverse ssh, I’ve run into paranoid sys admins who block the outgoing port 22 on their networks, which makes reverse ssh difficult.  Once you have the IP address of the broadband connection, you can connect to it directly with ssh from anywhere in the world.  I’ve accessed systems that were being field tested in New Zealand from the United States, and it worked great.&lt;&#x2F;p&gt;
&lt;p&gt;Increasingly, the value of complex embedded systems is shifting from control to data.  While the control aspect is as important as it ever was, access to data is what is giving many products and businesses the competitive edge.  Being able to collect data and visualize how the system is performing is becoming increasingly important to maximize performance.  And sometimes this data must be collected in real-time.  Scenarios where USB broadband modems might make sense:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;remote sites that do not have internet connectivity&lt;&#x2F;li&gt;
&lt;li&gt;mobile applications such as vehicle terminals&lt;&#x2F;li&gt;
&lt;li&gt;temporary installations where the system is only located in one place for a limited time&lt;&#x2F;li&gt;
&lt;li&gt;situations where it is very difficult to get administrators of the local network to cooperate in adding the embedded system to their network&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;finding-ppp-config-information&quot;&gt;Finding PPP Config information&lt;&#x2F;h2&gt;
&lt;p&gt;I usually develop as much as I can on x86 systems (vs. an embedded target) as it is a lot more convenient, so I plugged the modem into a Ubuntu 8.10 laptop.  While Ubuntu 8.10 recognizes and configures a UM150 Verizon modem, it does not automatically configure the 598U.  Typically, the next step is to google around for information on various support forums on how to set up the PPP config files, as most manufactures don’t provide support for Linux.  As I could not find any existing information for the 598U, I decided to see if Sierra Wireless published any information.  Was I ever suprised when I found &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sierrawireless.custhelp.com&#x2F;app&#x2F;answers&#x2F;detail&#x2F;a_id&#x2F;500#supported_devices&quot;&gt;this page&lt;&#x2F;a&gt;.  Sierra Wireless provides fairly comprehensive information on using the modem under Linux, and their PPP scripts actually worked – great job!  But in the end, when I plugged the 598U into the embedded device that already supported the Verizon modem, it just worked with my existing PPP scripts.  This is another indication of the value of using common code and interfaces in Linux.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-linux-advantage&quot;&gt;The Linux Advantage&lt;&#x2F;h2&gt;
&lt;p&gt;When you run Linux in an embedded system, using a USB broadband modem becomes fairly simple.  It is actually a little bit deceiving as to what all has to happen.  Different modems use different chipsets, and thus different drivers.  While they all eventually expose a USB serial interface, there are enough differences to require separate drivers.  As an example, the 598U uses the “sierra” USB-serial driver.  This driver is 782 lines, plus it utilizes a common USB serial framework that is many times this size.  On the application side, the pppd framework is used to manage the modem and the network connection.  Starting the connection is as simple as running “pppd call cdma” from your application.  The pppd application manages getting an IP address, setting up nameservers in &lt;em&gt;resolve.conf&lt;&#x2F;em&gt;, etc.  Because all broadband modems are supported by a common application interface and very similiar drivers, supporting multiple modem vendors is actually quite easy.  Contrast this to the Windows driver scenario where every vendor provides their “own” driver, and their “own” application user interface, and their “own” way to initiate an internet connection, and it is not obvious to me how you could easily control all this in a consistent, automated fashion in an embedded device.  The way we set it up is you plug the modem in, and a few seconds later the system is automatically connected to the internet.   There is nothing for the user to configure, initiate, etc.  &lt;a href=&quot;&#x2F;218&#x2F;printing-from-embedded-systems&#x2F;&quot;&gt;Printing from Linux in embedded applications&lt;&#x2F;a&gt; is similiar.&lt;&#x2F;p&gt;
&lt;p&gt;This is another example of how it is possible to leverage the work of many to add advanced functionality and features to a device with very little development cost.  Getting more done with less should be an attractive (and perhaps critical) way to operate for any company seeking to remain competitive.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Socketcan utils and test apps added to OpenEmbedded</title>
        <published>2009-01-28T00:00:00+00:00</published>
        <updated>2009-01-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/346/socketcan-utils-and-test-apps-added-to-openembedded/"/>
        <id>https://bec-systems.com/346/socketcan-utils-and-test-apps-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/346/socketcan-utils-and-test-apps-added-to-openembedded/">&lt;p&gt;The Socketcan test applications and utilities are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;packages&#x2F;socketcan&#x2F;socketcan-utils-test_svn.bb&quot;&gt;now available in OpenEmbedded&lt;&#x2F;a&gt;.  The socketcan kernel modules &lt;a href=&quot;&#x2F;341&#x2F;socketcan-can-bus-drivers-added-to-openembedded&#x2F;&quot;&gt;already exist in OE&lt;&#x2F;a&gt;.  To build and deploy:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;get the latest version of OE metadata&lt;&#x2F;li&gt;
&lt;li&gt;bitbake socketcan-utils-test&lt;&#x2F;li&gt;
&lt;li&gt;scp &lt;oedir&gt;&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;&lt;machine&gt;&#x2F;socketcan-utils-test_0.0+svnr917-r0_armv5te.ipk root@&lt;target IP address&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And then on the target system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;opkg install socketcan-utils-test_0.0+svnr917-r0_armv5te.ipk&lt;&#x2F;li&gt;
&lt;li&gt;opkg files socketcan-utils-test&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;usr&#x2F;bin&#x2F;tst_bcm_rx_sendto
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_tx_sendto
&#x2F;usr&#x2F;bin&#x2F;canlogserver
&#x2F;usr&#x2F;bin&#x2F;tst_raw_filter
&#x2F;usr&#x2F;bin&#x2F;tst_raw
&#x2F;usr&#x2F;bin&#x2F;isotpsniffer
&#x2F;usr&#x2F;bin&#x2F;isotpsend
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_throttle
&#x2F;usr&#x2F;bin&#x2F;tst_packet
&#x2F;usr&#x2F;bin&#x2F;vcan
&#x2F;usr&#x2F;bin&#x2F;isotprecv
&#x2F;usr&#x2F;bin&#x2F;cansniffer
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_tx_read
&#x2F;usr&#x2F;bin&#x2F;tst_err
&#x2F;usr&#x2F;bin&#x2F;log2asc
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_single
&#x2F;usr&#x2F;bin&#x2F;tst_filter_master
&#x2F;usr&#x2F;bin&#x2F;canplayer
&#x2F;usr&#x2F;bin&#x2F;cangen
&#x2F;usr&#x2F;bin&#x2F;slcanpty
&#x2F;usr&#x2F;bin&#x2F;log2long
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_rtr
&#x2F;usr&#x2F;bin&#x2F;asc2log
&#x2F;usr&#x2F;bin&#x2F;slcan_attach
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_filter
&#x2F;usr&#x2F;bin&#x2F;cansend
&#x2F;usr&#x2F;bin&#x2F;canecho
&#x2F;usr&#x2F;bin&#x2F;tst_filter_server
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_cycle
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_dump
&#x2F;usr&#x2F;bin&#x2F;isotpdump
&#x2F;usr&#x2F;bin&#x2F;candump
&#x2F;usr&#x2F;bin&#x2F;tst_raw_sendto
&#x2F;usr&#x2F;bin&#x2F;isotptun
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_server
&#x2F;usr&#x2F;bin&#x2F;tst_proc
&#x2F;usr&#x2F;bin&#x2F;canbusload
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An impressive array of utilities!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Socketcan CAN-bus drivers added to OpenEmbedded</title>
        <published>2009-01-26T00:00:00+00:00</published>
        <updated>2009-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/341/socketcan-can-bus-drivers-added-to-openembedded/"/>
        <id>https://bec-systems.com/341/socketcan-can-bus-drivers-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/341/socketcan-can-bus-drivers-added-to-openembedded/">&lt;p&gt;I just added a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;packages&#x2F;socketcan&#x2F;socketcan-modules_svn.bb&quot;&gt;recipe&lt;&#x2F;a&gt; to OpenEmbedded to build the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;developer.berlios.de&#x2F;projects&#x2F;socketcan&#x2F;&quot;&gt;Socketcan&lt;&#x2F;a&gt; kernel modules from the socketcan SVN.  So if you are using the latest OpenEmbedded metadata, you can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;bitbake socketcan-modules&lt;&#x2F;li&gt;
&lt;li&gt;scp &lt;oedir&gt;&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;&lt;machine&gt;&#x2F;socketcan-modules_0.0+svnr917-r0_cm-x270.ipk  root@&lt;target IP address&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;and then on the target system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;opkg install socketcan-modules_0.0+svnr917-r0_cm-x270.ipk&lt;&#x2F;li&gt;
&lt;li&gt;opkg files socketcan-modules&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre&gt;&lt;code&gt;Package socketcan-modules (0.0+svnr917-r0) is installed on root and has the following files:
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can-bcm.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;ems_pci.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can-raw.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;sja1000.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;softing&#x2F;softing.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;ems_pcmcia.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;sja1000_platform.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;can-dev.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;softing&#x2F;softing_cs.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;pipcan.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;mcp251x.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can-isotp.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;vcan.ko
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then to use the modules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;depmod&lt;&#x2F;li&gt;
&lt;li&gt;modprobe mcp251x&lt;&#x2F;li&gt;
&lt;li&gt;modprobe can-bcm&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What is CAN?  Can stands for Controller-area network and is popular in industrial and automotive applications.  A convenient way to add CAN to your Embedded Linux system is with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.microchip.com&#x2F;wwwproducts&#x2F;Devices.aspx?dDocName=en010406&quot;&gt;Microchip MCP2515&lt;&#x2F;a&gt;.  This device connects to a SPI bus which means it can be interfaced with a number of popular SOC’s such as the PXA270, OMAP3, 91SAM9xxx, etc.&lt;&#x2F;p&gt;
&lt;p&gt;More on Socketcan later …&lt;&#x2F;p&gt;
&lt;p&gt;BTW, this recipe really illustrates how easy it is to compile kernel modules outside a kernel in OpenEmbedded:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DESCRIPTION = &amp;quot;Socketcan kernel modules&amp;quot;
HOMEPAGE = &amp;quot;http:&#x2F;&#x2F;developer.berlios.de&#x2F;projects&#x2F;socketcan&#x2F;&amp;quot;
SECTION = &amp;quot;kernel&#x2F;modules&amp;quot;
LICENSE = &amp;quot;GPL&amp;quot;
DEPENDS = &amp;quot;virtual&#x2F;kernel&amp;quot;
PV = &amp;quot;0.0+svnr${SRCREV}&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;svn.berlios.de&#x2F;socketcan&#x2F;trunk;module=kernel;proto=svn&amp;quot;

S = &amp;quot;${WORKDIR}&#x2F;kernel&#x2F;2.6&amp;quot;

inherit module
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This recipe tells OE to download the source, cross-compile it against your target kernel build dir, and then package it for easy install on the device.  This is the way things should work – no messing around figuring out make options, kernel source paths, compiler env variables, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Intel Atom vs TI OMAP3</title>
        <published>2009-01-22T00:00:00+00:00</published>
        <updated>2009-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/326/intel-atom-vs-ti-omap3/"/>
        <id>https://bec-systems.com/326/intel-atom-vs-ti-omap3/</id>
        
        <content type="html" xml:base="https://bec-systems.com/326/intel-atom-vs-ti-omap3/">&lt;p&gt;As we look at new projects, both the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.intel.com&#x2F;technology&#x2F;atom&#x2F;index.htm&quot;&gt;Intel Atom&lt;&#x2F;a&gt; and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;focus.ti.com&#x2F;paramsearch&#x2F;docs&#x2F;parametricsearch.tsp?family=dsp&amp;amp;sectionId=2&amp;amp;tabId=2225&amp;amp;familyId=1526&amp;amp;paramCriteria=no&quot;&gt;TI OMAP3&lt;&#x2F;a&gt; processors generate considerable interest.  As &lt;a href=&quot;&#x2F;316&#x2F;gtk-performance-on-pxa270-vs-omap3&#x2F;&quot;&gt;we have already shown&lt;&#x2F;a&gt;, the OMAP3 does offer a considerable performance improvement over earlier generations of ARM CPUs.  The following &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=cnsaDc6criM&quot;&gt;video&lt;&#x2F;a&gt; I found on YouTube shows a similar comparison of a OMAP3 and Atom systems rendering web pages:&lt;&#x2F;p&gt;
&lt;p&gt;As one would expect, the Atom does perform better (about 14%), but considering the power differences, the OMAP does surprisingly well.  It is also unknown in this demo if the screen size would make a significant difference in the results.  Like most things, the choice depends on the application, and no two applications are the same, and each solution has advantages.  Some things to think about:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Power: OMAP3 platform consumes on the order of &amp;lt;1-2W while the Atom is more in the range of 2-5W.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;High Speed I&#x2F;O Interfaces: Atom supports PCI and PCI expansion interfaces where OMAP3 is limited to more special purpose user interfaces such as SD, Camera, Asynchronous bus, etc.  Both Atom and OMAP support High Speed USB.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Packaging: OMAP3 packaging is very aggressive with the stacked Package-on-Package.  To get an idea how much space an OMAP3 solution takes, check out the module from &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gumstix.com&#x2F;store&#x2F;catalog&#x2F;product_info.php?products_id=211&quot;&gt;Gumstix&lt;&#x2F;a&gt;.  There are basically only two chips in the system: the OMAP3+stacked RAM&#x2F;Flash and a power management+I&#x2F;O chip.  This is very high integration!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Module availability: for many embedded systems with volumes in the 1000’s of units per year, a module solution is very attractive compared to a full custom design.  This drastically reduces the engineering effort and time to market.  A sampling of the modules available include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OMAP3:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gumstix.com&#x2F;store&#x2F;catalog&#x2F;product_info.php?products_id=211&quot;&gt;Gumstix Overo&lt;&#x2F;a&gt; ($117 for 3000 units)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.logicpd.com&#x2F;products&#x2F;som&#x2F;ti&#x2F;omap35x&quot;&gt;LogicPD OMAP35x SOM-LV&lt;&#x2F;a&gt; (Cost unknown)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Atom:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.eurotech-inc.com&#x2F;single-board-computer-atom-com-catalyst-module.asp&quot;&gt;Eurotech Catalyst&lt;&#x2F;a&gt; (Cost unknown)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Software support:  TI and the open source community have done a remarkable job of supporting the OMAP3 with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;beagleboard.org&#x2F;&quot;&gt;BeagleBoard&lt;&#x2F;a&gt; effort.  Gumstix maintains open source software for their devices, and has a very active development community.  Intel also has invested significantly in software with their &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;moblin.org&#x2F;&quot;&gt;Moblin&lt;&#x2F;a&gt; project.  Other factors to consider is the boot software (bootloader vs BIOS, is it open?), are there 3D graphics libraries available, etc.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Multimedia processing:  The OMAP3 is available with an on-chip DSP.  Intel has traditionally offered extensions for multimedia processing such as SIMD.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Tradeoffs!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GTK performance on PXA270 vs. OMAP3</title>
        <published>2009-01-21T00:00:00+00:00</published>
        <updated>2009-01-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/316/gtk-performance-on-pxa270-vs-omap3/"/>
        <id>https://bec-systems.com/316/gtk-performance-on-pxa270-vs-omap3/</id>
        
        <content type="html" xml:base="https://bec-systems.com/316/gtk-performance-on-pxa270-vs-omap3/">&lt;p&gt;Several of my customers have built applications using the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.gtk.org&#x2F;&quot;&gt;GTK+&lt;&#x2F;a&gt; tookit.  While GTK+ works fairly well for what we have done, I have been wondering how the performance compares on the new &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;focus.ti.com&#x2F;general&#x2F;docs&#x2F;gencontent.tsp?contentId=36915&quot;&gt;Omap3&lt;&#x2F;a&gt; processors from TI. As we are evaluating the OMAP3 for several projects, I did a simple comparison with an existing application.  Below is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=VKl5GRNLH4k&quot;&gt;video&lt;&#x2F;a&gt; that shows a fairly complex application running on both a PXA270, and a OMAP3530.  While the PXA270 gets the job done, the result on the OMAP3 is much more pleasing.  With that advent of a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gumstix.com&#x2F;store&#x2F;catalog&#x2F;product_info.php?products_id=211&quot;&gt;OMAP3 module available for $117 in volume&lt;&#x2F;a&gt;, it seems like the OMAP3 will be a popular solution for upcoming Embedded Linux projects.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fix for PXA270 MMC&#x2F;SD Controller Write Corruption</title>
        <published>2009-01-17T00:00:00+00:00</published>
        <updated>2009-01-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/314/fix-for-pxa270-mmcsd-controller-write-corruption/"/>
        <id>https://bec-systems.com/314/fix-for-pxa270-mmcsd-controller-write-corruption/</id>
        
        <content type="html" xml:base="https://bec-systems.com/314/fix-for-pxa270-mmcsd-controller-write-corruption/">&lt;p&gt;During system verification for a customer, we noticed occasional failures when writing to a SD card using the Marvell PXA270 MMC&#x2F;SD controller.  The failure is a 4KB block of data is shifted on byte, where the first byte is duplicated and the last byte is dropped. The test app that found this problem is available &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dev.bec-systems.com&#x2F;redmine&#x2F;bec&#x2F;repositories&#x2F;browse&#x2F;miscsrc&#x2F;fs_stress_test&quot;&gt;here&lt;&#x2F;a&gt;.  This test app simulates an application that writes data to a SD card at a certain rate.  We found that typically in about 2000 - 10000 hours of simulated testing, we would see a failure.  Its very interesting that the field failure rates matched this rate as well.&lt;&#x2F;p&gt;
&lt;p&gt;This failure had all the signs of a hardware (likely DMA) problem, and sure enough there is a Marvell Eratta for this issue.  A patch has been developed and tested by several people and is available in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lists.arm.linux.org.uk&#x2F;lurker&#x2F;message&#x2F;20090117.220838.f9e6472f.en.html&quot;&gt;this mail thread&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Installing Ubuntu on a Core i7 DX58SO motherboard</title>
        <published>2009-01-15T00:00:00+00:00</published>
        <updated>2009-01-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/302/getting-linux-on-a-dx58so/"/>
        <id>https://bec-systems.com/302/getting-linux-on-a-dx58so/</id>
        
        <content type="html" xml:base="https://bec-systems.com/302/getting-linux-on-a-dx58so/">&lt;p&gt;&lt;strong&gt;UPDATE:  2009-03-17 – It appears that hard drive issues I encountered are likely due to the HW RAID formatting on the drive I tried.  I just tried a brand new hard drive, and Ubuntu 8.10 installed flawlessly, and everything works.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I’m not sure why computer upgrades are always such an epic struggle for me, but here I go again …&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to upgrade my aging AMD X2 system to a new Intel Core i7 system.  So after researching it a bit, I decided on the Intel &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.intel.com&#x2F;products&#x2F;desktop&#x2F;motherboards&#x2F;DX58SO&#x2F;DX58SO-overview.htm&quot;&gt;DX58SO&lt;&#x2F;a&gt; motherboard.  I liked the architecture, and have had good luck with Intel motherboards.  And since I don’t upgrade all that often, I try to get something good when I do.  As I learned later, I should have researched Linux compatibility a little more …&lt;&#x2F;p&gt;
&lt;p&gt;The plan was to simply replace the CPU&#x2F;MB&#x2F;RAM in my existing box as I already have a raid controller, decent case, etc.  However, the first challenge was the existing PS does not supply a EPS&#x2F;ATX12V8 pin connector – it only had the 4-pin version.  So, I got to upgrade my PS to a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.corsair.com&#x2F;products&#x2F;tx&#x2F;default.aspx&quot;&gt;Corsair CMPSU-650TX&lt;&#x2F;a&gt; which seems very nice, and quiet.&lt;&#x2F;p&gt;
&lt;p&gt;After I put everything together, the raid array (3ware 9500S-4LP PCI) was detected, but the system would not boot.  So I booted from a Ubuntu install disk and selected boot from 1st hard disk, and then it seemed to boot fine.  However, the Ethernet controller and CDROM don’t work under Ubuntu 8.04 (64-bit) which was currently installed on the raid array.  However, everything else works pretty well, and it is quite fast.  Because the core-i7 brought back hyperthreading, Linux now shows 8 cores.&lt;&#x2F;p&gt;
&lt;p&gt;Several days later in an attempt to get the system booting from the hard drive, I upgraded the BIOS to the latest version.  However, this broke booting from the raid array; even with a Ubuntu install disk.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, I decided to just rebuild the system by re-configuring the 4 hard drives currently in a hardware raid-5 array to two raid-1 software raid arrays.  As the raid card is only PCI, I think this would provide better performance and be simpler to maintain in the future.  So, I copy all my data off to a USB HD, and then try to install Ubuntu to a HD attached to the motherboard.  To my suprise, I can’t get MB attached hard drives to work.  Lots of messages like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[  361.943329] ata1.01: status: { DRDY ERR }
[  361.943332] ata1.01: error: { ABRT }
[  362.043760] ata1.01: configured for UDMA&#x2F;133
[  362.043771] ata1: EH complete
[  362.218194] ata1.01: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[  362.218200] ata1.01: BMDMA stat 0x45
[  362.218207] ata1.01: cmd c8&#x2F;00:08:00:00:00&#x2F;00:00:00:00:00&#x2F;f0 tag 0 dma 4096 in
[  362.218209]          res 51&#x2F;04:08:00:00:00&#x2F;04:00:1d:00:00&#x2F;f0 Emask 0x1 (device error)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I tried booting a 32-bit Ubuntu 8.10 live CD and I get the same thing when trying to fdisk a hard drive attached to the MB.  So for now, the only way to get this running is to go back to the old RAID controller.  Fortunately, Intel keeps old BIOS versions on their web site and after two tries, I was able to find one that works again with the HW RAID controller.&lt;&#x2F;p&gt;
&lt;p&gt;The Ethernet and CD ROM did work with the Ubuntu 8.10 32-bit live CD, so once I upgrade to 8.10, hopefully that will all work.  So for now, I’ll limp along with my raid controller and a USB-&amp;gt;Ethernet adapter for networking.&lt;&#x2F;p&gt;
&lt;p&gt;Anyone else have success with Linux on the DX58SO?&lt;&#x2F;p&gt;
&lt;p&gt;I’ve filed a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;ubuntu&#x2F;+bug&#x2F;317607&quot;&gt;bug on launchpad&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Switching to Wordpress</title>
        <published>2009-01-13T00:00:00+00:00</published>
        <updated>2009-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/296/switching-to-wordpress/"/>
        <id>https://bec-systems.com/296/switching-to-wordpress/</id>
        
        <content type="html" xml:base="https://bec-systems.com/296/switching-to-wordpress/">&lt;p&gt;After using Joomla for several years, I’m switching my web site to wordpress.  As I mostly use my site for writing technical articles, it makes sense to use something that works very well for just that.  So far, I’m finding Wordpress very polished, and it has all the functionality I need built-in, so I don’t have to rely on 3rd party modules for very basic operations like tagging, RSS feeds, comments, etc.  Now I have no excuse for now writing more as Wordpress works so well.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mono 2.2 RC1 added to Openembedded</title>
        <published>2009-01-10T00:00:00+00:00</published>
        <updated>2009-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/274/mono-2-2-rc1-added-to-openembedded/"/>
        <id>https://bec-systems.com/274/mono-2-2-rc1-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/274/mono-2-2-rc1-added-to-openembedded/">&lt;p&gt;I recently added&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;packages&#x2F;mono&quot;&gt;Mono 2.2 RC1 to OpenEmbedded&lt;&#x2F;a&gt;.  The last usable version of Mono in Openembedded was 1.2.6, so this is a big step up.  Lots of interesting things have been happening since then (like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;tirania.org&#x2F;blog&#x2F;archive&#x2F;2008&#x2F;Nov-05.html&quot;&gt;Full Static Compilation&lt;&#x2F;a&gt;) that continue to make Mono interesting for embedded.  There is still plenty to do yet such as clean up the packaging, and update the other related recipes such as mono-xsp, and gtk-sharp.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using the Vala Programming Language in Embedded Systems</title>
        <published>2009-01-10T00:00:00+00:00</published>
        <updated>2009-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/277/using-the-vala-programming-language-in-embedded-systems/"/>
        <id>https://bec-systems.com/277/using-the-vala-programming-language-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/277/using-the-vala-programming-language-in-embedded-systems/">&lt;p&gt;Recently I’ve been following the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;live.gnome.org&#x2F;Vala&quot;&gt;Vala programming language&lt;&#x2F;a&gt; and using it some in embedded systems.  Vala is a new programming language that aims to bring modern programming features to GNOME developers without imposing additional runtime requirements and without using a different ABI compared to applications and libraries written in C.  A few notes and observations about Vala:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;language syntax that resembles C#, so you can write code faster with less mistakes&lt;&#x2F;li&gt;
&lt;li&gt;Vala compiles to C, so it starts fast and runs fast like native applications&lt;&#x2F;li&gt;
&lt;li&gt;binaries are not platform independent  (like Mono or Java)&lt;&#x2F;li&gt;
&lt;li&gt;lots of bindings already exist, as it is very easy to write bindings to existing C libraries&lt;&#x2F;li&gt;
&lt;li&gt;easy to write programs that are mixed C and Vala&lt;&#x2F;li&gt;
&lt;li&gt;documentation is still a bit sparse, so you end up reading the binding files to figure out how to use the libraries&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Much of the core Vala functionality is built on top of Glib.  Having programmed extensively with Glib, I can say programming in Vala is a lot more fun, and a lot less tedious.  Vala also provides dynamic D-Bus bindings which makes if very nice for writing system daemons or other bits of software that need to implement a D-Bus server.&lt;&#x2F;p&gt;
&lt;p&gt;As far as real world experience, in a recent application, we ported a system monitoring application from C# to Vala.  There were no real serious problems with the original application, but it started slow (7 seconds or so), and the customer wanted to reduce the boot time of the system.  Once you get past the core language syntax, the libraries for Vala are all different than C#, so most of the library function calls needed tweaked a little.  Most of the functionality was implemented with Vala, but there were a few minor functions that were implemented in C.  It now starts fast, which is what we needed.&lt;&#x2F;p&gt;
&lt;p&gt;We are also using the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.freesmartphone.org&#x2F;?p=openmoko-gsoc2008.git;a=tree;f=fsod&quot;&gt;fsod&lt;&#x2F;a&gt; application from the OpenMoko project in a customer project.  This is an excellent example of a well written, advanced Vala project that uses features such as plugins and D-Bus.&lt;&#x2F;p&gt;
&lt;p&gt;Watching the releases from the Vala project, it is amazing the progress this language is making.  I’m sure we’ll be hearing more about Vala in the future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to implement an interrupt driven GPIO input in Linux</title>
        <published>2009-01-10T00:00:00+00:00</published>
        <updated>2009-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux/"/>
        <id>https://bec-systems.com/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux/">&lt;p&gt;With Linux, some of the things that seem like they should be easy are not – at least at first glance.  For example, how do you read an interrupt driven GPIO input in a Linux application?  With simpler microcontroller systems, this is straightforward, but with a system like Linux, you have to navigate through several layers of software (and for very good reasons).  You can’t handle interrupts directly in a Linux application, so this means you need a kernel component involved.  This operation of reading a GPIO resembles a key press, so the Linux input subsystem might be a good place to start looking.  Once we take that route, we discover the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux-2.6.git;a=blob;f=drivers&#x2F;input&#x2F;keyboard&#x2F;gpio_keys.c&quot;&gt;gpio_keys&lt;&#x2F;a&gt; driver.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-the-gpio-keys-driver&quot;&gt;Configuring the gpio_keys driver&lt;&#x2F;h2&gt;
&lt;p&gt;The gpio_keys driver is configured with a few lines of code in your Linux board configuration file.  An example is below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;static struct gpio_keys_button svs_button_table[] = {
  { .code = KEY_RECORD,
    .gpio = PP_GPIO_MIC_EN,
    .active_low = 1,
    .desc = &amp;quot;MIC_EN&amp;quot;,
    .type = EV_KEY,
    .wakeup = 0,
  },
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this application, we are reading button presses on a cell phone style headset.  Once the gpio_keys driver is configured, a new entry will show up in &#x2F;dev&#x2F;input&#x2F;eventX.  An application can then do a blocking read on this device.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reading-the-gpio-in-an-application&quot;&gt;Reading the GPIO in an application&lt;&#x2F;h2&gt;
&lt;p&gt;To read the GPIO, we simply do a blocking read on the new &#x2F;dev&#x2F;input&#x2F;eventX device.  The read will block until there is a change in GPIO state.  An example is show below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#define MIC_INPUT_DEV  &amp;quot;&#x2F;dev&#x2F;input&#x2F;event0&amp;quot;

static gboolean mic_button_callback(GIOChannel *source, GIOCondition condition, gpointer data)
{
  struct input_event ev;
  int bytes_read;

g_io_channel_read_chars(source, (gchar *)&amp;amp;ev, sizeof(ev), &amp;amp;bytes_read, NULL);

if (bytes_read &amp;gt; 0) {
    if (bytes_read != sizeof(ev)) {
      s_debug(1, &amp;quot;warning, only read %i bytes from mic input&amp;quot;);
      return TRUE;
    }
  } else {
    return TRUE;
  }

if (ev.type != EV_SYN &amp;amp;&amp;amp; ev.value == 1) {
    &#x2F;* button pressed, do something ... *&#x2F;
  }

return TRUE;
}

void mic_button_init()
{
  GIOChannel * micbutton = g_io_channel_new_file(MIC_INPUT_DEV, &amp;quot;r&amp;quot;, NULL);

if (micbutton == NULL) {
    s_debug(TRUE, &amp;quot;Error initializing mic button&amp;quot;);
    return;
  }

g_io_channel_set_encoding(micbutton, NULL, NULL);

guint id = g_io_add_watch(micbutton, G_IO_IN, mic_button_callback, NULL);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above example also shows how to incorporate the GPIO read into a GLib mainloop so that you don’t need to create a separate thread. ( As a side, GLib mainloop programming is worth learning!)  Using this method, reading a GPIO interrupt is easy and requires very few lines of code.  This is typical of complex systems like Linux – if you know how to do something, it is relatively easy, but getting started down the right path is sometimes the challenge.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tips for reading a serial data stream in Python</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/257/tips-for-reading-a-serial-data-stream-in-python/"/>
        <id>https://bec-systems.com/257/tips-for-reading-a-serial-data-stream-in-python/</id>
        
        <content type="html" xml:base="https://bec-systems.com/257/tips-for-reading-a-serial-data-stream-in-python/">&lt;p&gt;Interfacing with a RS232 serial device is a common task when using Python in embedded applications.  The easiest way to get python talking to serial ports is use the pyserial project found at  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;pyserial.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;pyserial.sourceforge.net&#x2F;&lt;&#x2F;a&gt;.  This module works on most platforms and is straightforward to use (see examples on project web site). However, getting the read function in this module to operate in an optimal way takes a little study and thought.  This article investigates how the pyserial module works, possible issues you might encounter, and how to optimize serial reads.&lt;&#x2F;p&gt;
&lt;p&gt;We start out with several goals as to how we want the application to behave in relation to the serial port:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;application must block while waiting for data.&lt;&#x2F;li&gt;
&lt;li&gt;for performance reasons, we want to read decent size chunks of data at a time if possible.  Python function calls are expensive, so performance will be best if we can read more than one byte at a time.&lt;&#x2F;li&gt;
&lt;li&gt;We want any data received returned in a timely fashion.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A key parameter in the pyserial &lt;em&gt;Serial&lt;&#x2F;em&gt; class is the &lt;em&gt;timeout&lt;&#x2F;em&gt; parameter.  This parameter is defined as:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; timeout=None,           #set a timeout value, None for waiting forever
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;Serial&lt;&#x2F;em&gt; class &lt;em&gt;read&lt;&#x2F;em&gt; function also accepts a &lt;em&gt;size&lt;&#x2F;em&gt; parameter that indicates how many characters should be read.  Below is the source for the read function on Posix systems (Linux, etc):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;     def read(self, size=1):
        &amp;quot;&amp;quot;&amp;quot;Read size bytes from the serial port. If a timeout is set it may
           return less characters as requested. With no timeout it will block
           until the requested number of bytes is read.&amp;quot;&amp;quot;&amp;quot;
        if not self.fd: raise portNotOpenError
        read = &amp;#39;&amp;#39;
        inp = None
        if size &amp;gt; 0:
            while len(read) &amp;lt; size:
                #print &amp;quot;\tread(): size&amp;quot;,size, &amp;quot;have&amp;quot;, len(read)    #debug
                ready,_,_ = select.select([self.fd],[],[], self.timeout)
                if not ready:
                    break   #timeout
                buf = os.read(self.fd, size-len(read))
                read = read + buf
                if self.timeout &amp;gt;= 0 and not buf:
                    break  #early abort on timeout
        return read
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The easy way to use this module is to simply set the timeout to None, and read size to 1.  This will return any data received immediately.  But, this setup is very inefficient when transferring large amounts of data due to the Python processing overhead.&lt;&#x2F;p&gt;
&lt;p&gt;To meet our goal of reading multi-byte blocks of data at a time, we need to pass the read function a size greater than 1.  However, if timeout is set to None, the read will block until size bytes have been read, which does not meet the goal of returning any data read in a timely fashion.  The solution then is to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;set the read size high enough to get good performance&lt;&#x2F;li&gt;
&lt;li&gt;set the timeout low enough so that any data received is returned in a reasonable timeframe, but yet the application spends most of its time blocked if there is no data.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As an example, a size of 1000 and a timeout of 1 second seems to perform well.  When used this way, the pyserial module performs well and returns all data read quickly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Optimize Python reads for general data</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/259/how-to-optimize-python-reads-for-general-data/"/>
        <id>https://bec-systems.com/259/how-to-optimize-python-reads-for-general-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/259/how-to-optimize-python-reads-for-general-data/">&lt;p&gt;The Python file object read() function acts a little differently than the standard read() found in C.  This article describes some of these differences and how to optimize reads for general continuous data streams such as reading data from a collection device through a pipe.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python-read&quot;&gt;Python read()&lt;&#x2F;h2&gt;
&lt;p&gt;The Python read function seems to be optimized for reading files and text oriented streams.  By default, a read() call will block until a EOF is encountered.  This is very handy for reading files from a disk.  You can just slurp them up with one read() statement.  If you pass a size parameter to read(), it will block until size bytes have been received.  This is less than ideal for reading a continuous data stream where some of thye data may be stuck until the size threshhold is reached.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;non-blocking-read&quot;&gt;Non-blocking read()&lt;&#x2F;h2&gt;
&lt;p&gt;The way you get read to return with whatever data is available even if it is less than the read size parameter is to set the file object up in non-blocking mode.  This can be done using the fcntl module:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 		flags = fcntl.fcntl(fp, fcntl.F_GETFL)
            	fcntl.fcntl(fp, fcntl.F_SETFL, flags | os.O_NONBLOCK)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, now the application does not block while waiting for data and spins using CPU resources.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;select&quot;&gt;select()&lt;&#x2F;h2&gt;
&lt;p&gt;Enter the select call.  The Python select module does much the same thing as the C select() function.  In this case, it can be used to block waiting for data from a non-blocking file object with the added benefit of a timeout.  So the resulting code might look like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 	fp = os.popen(&amp;lt;application that returns data to stdout&amp;gt;, &amp;#39;r&amp;#39;)

flags = fcntl.fcntl(fp, fcntl.F_GETFL)
    	fcntl.fcntl(fp, fcntl.F_SETFL, flags | os.O_NONBLOCK)

while 1:
		[i, o, e] = select.select([fp], [], [], 5)
		if i: s_ = fp.read(1000)
		else: s_ = &amp;#39;&amp;#39;

if s_:
			logging.debug(&amp;quot;received %i bytes of data, total = %i&amp;quot; % (len(s_), total))
			&amp;lt;do something with s_&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above select statement blocks until data is available from the fp object or times out after 5 seconds.  Reading continuous data streams in Python is very possible, but usually requires the file object to be set in non-blocking mode and a select used to block while waiting for data.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Implementing Asterisk</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/262/implementing-asterisk/"/>
        <id>https://bec-systems.com/262/implementing-asterisk/</id>
        
        <content type="html" xml:base="https://bec-systems.com/262/implementing-asterisk/">&lt;p&gt;Over the past month, we have been working on implementing Asterisk in our office.  Asterisk (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.asterisk.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.asterisk.org&#x2F;&lt;&#x2F;a&gt; ) is a complete software PBX (Private Branch Exchange) that runs on top of Linux.  Asterisk supports a number of features commonly found in a PBX including voicemail, hosted conferencing, call queuing, and many other features.  Having a real PBX provides many benefits for a business and has the potential to improve our service and lower our costs.  Over the next couple months we will be writing about our experiences implementing Asterisk, tips for setting it up etc.&lt;&#x2F;p&gt;
&lt;p&gt;One of the most amazing things about Asterisk is its flexibility.  You can mix and match IP phones, traditional analog phones, soft phones, traditional PSTN lines, and VOIP services in about any way you want.  Our setup is fairly simple – IP phones and connections to the outside world using our PSTN land line.  We are also evaluating several VOIP providers and trying to determine if VOIP is viable.  Stay tuned …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Implement a Web Application Framework in an Embedded Linux System</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/40/web-application-framework-embedded-linux/"/>
        <id>https://bec-systems.com/40/web-application-framework-embedded-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/40/web-application-framework-embedded-linux/">&lt;p&gt;As devices are increasingly more networked, an embedded web server is becoming a standard way for users to interact with and configure an embedded device using a standard web browser.  As an example, most pieces of networking equipment (such as routers and wireless access points) are configured this way.  There are many ways to implement a web server.  One way is to just write a monolithic program that handles the requests and outputs HTML using print statements.  Without a lot of planning, you usually end up with something where logic is intermixed with presentation.  The disadvantage of such an approach is that it quickly becomes very difficult to maintain your web application as it grows and changes.  The current best practice with web application frameworks (such as Ruby on Rails) splits a web application into 3 distinct components (Model, View, Controller – MVC) so that changes to one component can be made with minimal impact to others.  This article details a solution used in a recent project to implement such an architecture  using the following open source components: SQLite, Clearsilver, and Python.  The challenge was to find a solution that performed acceptably on a resource constrained 130MHz ARM-Linux system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;components-used&quot;&gt;Components Used&lt;&#x2F;h2&gt;
&lt;p&gt;The requirements for the web application framework for this system are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Footprint must be fairly small – less than 10MiB.&lt;&#x2F;li&gt;
&lt;li&gt;Must enable us to implement a clean MVC type architecture.&lt;&#x2F;li&gt;
&lt;li&gt;Must support a high level language like python for rapid development.&lt;&#x2F;li&gt;
&lt;li&gt;Includes a database.&lt;&#x2F;li&gt;
&lt;li&gt;Reasonable performance – less than 1 second to render a typical page.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After researching and testing several options, the following components were chosen to implement the framework:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Web Server: Cherokee (1MiB)&lt;&#x2F;li&gt;
&lt;li&gt;Model: SQLite  (290KiB)&lt;&#x2F;li&gt;
&lt;li&gt;View: Clearsilver  (170KiB)&lt;&#x2F;li&gt;
&lt;li&gt;Controller: Python (2-3MiB)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;web_app_framework1-1.jpg&quot; alt=&quot;web_app_framework1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Total size for the above components is about 4MiB.&lt;&#x2F;p&gt;
&lt;p&gt;The following sequence occurs during a typical web transaction:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An HTTP request is received by Cherokee&lt;&#x2F;li&gt;
&lt;li&gt;If the request matches the URI for the web application, Cherokee forwards the request to the web application framework via CGI.&lt;&#x2F;li&gt;
&lt;li&gt;Clearsilver parses the HTTP headers (including CGI GET and POST parameters) and provides the data to python in a easy to access HDF format.&lt;&#x2F;li&gt;
&lt;li&gt;Python looks at the URI and dispatches the request to the appropriate function.  Data is extracted from the SQLite database and an HDF datastructure is created.&lt;&#x2F;li&gt;
&lt;li&gt;Clearsilver is called to render the appropriate template.  Data from the HDF datastructure is used in the template to provide the dynamic content in the page.&lt;&#x2F;li&gt;
&lt;li&gt;The rendered HTML is passed back to Cherokee, and is then returned to the user’s web browser.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each component is discussed in more detail in the following sections.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;performance&quot;&gt;Performance&lt;&#x2F;h2&gt;
&lt;p&gt;One of the issues with modern web frameworks is that most require a lot of processing power.  Many frameworks are written in an interpreted language which tend to be not very efficient on embedded systems such as the 130MHz ARM-Linux system used in this project.  As most of the application development for this project is done in Python, I tried several other Python based solutions with the following results:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Django&lt;&#x2F;strong&gt;: takes &lt;strong&gt;10&lt;&#x2F;strong&gt; seconds to render a page&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;webpy&lt;&#x2F;strong&gt;: takes &lt;strong&gt;5&lt;&#x2F;strong&gt; seconds to render a page&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clearsilver&#x2F;Python&lt;&#x2F;strong&gt;: takes about &lt;strong&gt;1&lt;&#x2F;strong&gt; second to render a page&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Anything over 1 second is very slow for a web interface.  With fastcgi, webpy could probably have been sped up to be acceptably fast, but I don’t think there is much hope for frameworks like django on this type of system.  I have read of similar experiences trying to run Ruby-on-Rails on ARM-Linux systems.  As I’m currently just using a basic CGI interface, the Clearsilver solution could also be sped up significantly as well, if the Python portion could be kept running between requests with fastcgi or a similar mechanism.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cherokee-web-server&quot;&gt;Cherokee Web Server&lt;&#x2F;h2&gt;
&lt;p&gt;A web application typically consists of a web server (like Apache) and a program that provides the dynamic web content.  Some of the functions of a web server are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;receives HTTP requests&lt;&#x2F;li&gt;
&lt;li&gt;handles the request by serving static files&#x2F;images or routes the request to a program that outputs dynamic content&lt;&#x2F;li&gt;
&lt;li&gt;authentication&lt;&#x2F;li&gt;
&lt;li&gt;encryption (SSL, TLS)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are many web servers that can be used in embedded devices.  Some of them are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lighttpd (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.lighttpd.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.lighttpd.net&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;thttpd (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.acme.com&#x2F;software&#x2F;thttpd&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.acme.com&#x2F;software&#x2F;thttpd&#x2F;&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;Appweb (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.appwebserver.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.appwebserver.org&#x2F;&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;Boa (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.boa.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.boa.org&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;Cherokee (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.cherokee-project.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.cherokee-project.com&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;SHTTPD (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;shttpd.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;shttpd.sourceforge.net&#x2F;&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cherokee was chosen for this application because it provides a good balance between the size and functionality I am looking for.  It is also included in the Openembedded (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;openembedded.org&lt;&#x2F;a&gt; ) build system I am using.  Other systems will have different requirements – use the one that fits your application best.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;clearsilver&quot;&gt;Clearsilver&lt;&#x2F;h2&gt;
&lt;p&gt;Clearsilver (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.clearsilver.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.clearsilver.net&#x2F;&lt;&#x2F;a&gt; ) is the real gem that was discovered during this exercise.   Clearsilver is a language-neutral HTML template system written in C.  It is used as the templating system for many high volume sites such as Google Groups 2.  Clearsilver also provides CGI handling functions and bindings to several languages including Python.  The fact that it is written in C and is fast for high volume sites also makes it &lt;em&gt;fast enough&lt;&#x2F;em&gt; on slower embedded systems.  Because Clearsilver is written in C, the templating system is already fast.  Parts or all of the application can also be moved to C as needed to get the required performance.  Having a performance upgrade path is nice.  Clearsilver also forces a strict separation of application logic and presentation templates, which keeps things in line with the MVC architecture.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sqlite&quot;&gt;SQLite&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.sqlite.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.sqlite.org&#x2F;&lt;&#x2F;a&gt; ) is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.  SQLite works as expected and also has bindings to a number of languages including Python.  A SQLite database is just a single file that requires no configuration, making it very easy to use.  The database engine runs in the same process as the application using it, which increases performance because there is no context switch when running database operations.   Because SQLite does not have its own process, it does not handle concurrency as well as other databases such as MySQL, but in an embedded system you seldom have more than one process using the database.  SQLite provides some support for concurrency with reader&#x2F;writer locks for the entire database.  If your application is not real busy, this is often adequate if you need two processes to share some data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python&quot;&gt;Python&lt;&#x2F;h2&gt;
&lt;p&gt;Python is the glue that ties things together in this web application framework.  It sits between Clearsilver and the database.  The advantages of using a language like Python are rapid development and an extensive library.  Python is considerably slower than C, but there is always the option to move parts of the application into C as needed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openembedded-build-system&quot;&gt;Openembedded Build System&lt;&#x2F;h2&gt;
&lt;p&gt;How does one put together a system with all these components?  The answer is the Openembedded Build System (OE) (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;openembedded.org&lt;&#x2F;a&gt;).  OE includes support for all of the components discussed in this article.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The combination of Python, Clearsilver, and SQLite provides a compelling solution for a web application framework in an Embedded Linux System.  The solution is reasonably small, performs well, and provides a path to improve performance if needed.  We also get a clean architecture to create clean, maintainable web applications.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;About the author&lt;&#x2F;strong&gt; – Cliff Brake owns BEC Systems, a consulting operation that helps customers utilize modern computer technologies in their products.  BEC offers a range of services to make your embedded project a success including technology selection, development, troubleshooting, and training.  Please visit our website (&lt;a href=&quot;..&#x2F;..&#x2F;&quot;&gt;http:&#x2F;&#x2F;bec-systems.com&lt;&#x2F;a&gt; ) for more information and other free resources.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Do you have an Exit Strategy?</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/73/do-you-have-an-exit-strategy/"/>
        <id>https://bec-systems.com/73/do-you-have-an-exit-strategy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/73/do-you-have-an-exit-strategy/">&lt;p&gt;Some time ago, eWeek published in interesting article by Scott McNealy named “&lt;em&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.eweek.com&#x2F;article2&#x2F;0,1895,1907211,00.asp&quot;&gt;Technology’s Barriers to Exit&lt;&#x2F;a&gt;”&lt;&#x2F;em&gt;.  In this article, Scott makes an interesting point about considering the cost of technology.  There are three costs to consider:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cost of acquisition&lt;&#x2F;li&gt;
&lt;li&gt;ongoing cost&lt;&#x2F;li&gt;
&lt;li&gt;cost to exit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Scott states that most people analyze the first two costs fairly well.  What is not thought about as much is the the cost to exit – how do I move on to the next thing.  I think these basic questions apply very much to embedded technology decisions.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the time we carefully consider our requirements, think about ongoing manufacturing costs, etc.  There may be some thought given to upgrading (the exit), but we encounter several difficulties when planning for the future with complex embedded systems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;we often can’t predict what technologies will be available in the future&lt;&#x2F;li&gt;
&lt;li&gt;if may be difficult to predict our product requirements in the future&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As an example, we may have a product with an ethernet networking interface, and two years after product launch we have an opportunity that requires a wireless network interface.  How much is it going to cost to add wireless support to our product?  If the product is based on technologies that do not fundamentally support wireless networking, we are looking at very costly exit strategy.  Another example is application-specific, off-the-shelf solutions.  While these are great for many problems and provide a quick way to get something working, what happens when we want to upgrade?  Do we have to re-implement the entire system?&lt;&#x2F;p&gt;
&lt;p&gt;How does one hedge against the unknowns in the future?  One way is to try to anticipate every possible requirement and design it in.  I think this is bad strategy because you usually end up spending a lot of time working on things you don’t really need and the quality of the product suffers.  A better approach is make sure your product does what it needs to do well and is based on a flexible platform where significant parts of your design and software can be re-used in future versions.  This approach has many parallels to recent trends in software development and manufacturing such as Agile Software Development, and Lean Manufacturing.&lt;&#x2F;p&gt;
&lt;p&gt;Follow Scott’s advice and make technology selection decisions with the following questions in mind:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Is the technology based on open standards?&lt;&#x2F;li&gt;
&lt;li&gt;Are programming interfaces and protocols open, published, and been adopted by industry?&lt;&#x2F;li&gt;
&lt;li&gt;Is there a community process behind the technology (not just one company)?&lt;&#x2F;li&gt;
&lt;li&gt;Can the same technology be sourced from multiple companies?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The use of Linux in embedded systems is an excellent example of a technology that meets the above criteria.  You can develop your prototype on a x86 PC.  Move it to an embedded ARM single board computer (SBC) for the first production run.  Switch to a different SBC or design your own board when you run into new product requirements.  Sure, it will cost you more to develop the product initially due to the complexity of a system like Linux, but you now have options to expand and change your product while directly re-using the work you have already done.&lt;&#x2F;p&gt;
&lt;p&gt;But wait, as long as I write my application in C, it is portable – right?  Most embedded systems support development in C so I will just port my application to a new platform when needed.  C is a great language and the &lt;em&gt;language&lt;&#x2F;em&gt; is more or less portable between systems.  But as systems get more and more complex, embedded engineers find themselves spending less time writing original code and spending more time putting together pieces that already exist.  A modern embedded application is often little more than some glue between various libraries and system functions.  The fact that you can develop in C for a particular system does not really mean a lot.  What about the threading model, driver model, library APIs, etc.  I just spent a significant amount of time recently porting a large C application from a proprietary platform to new hardware platform as the original system was going obsolete.  It was a huge amount of work.  The driver model was completely different, APIs were different.  Changing platforms can be very expensive.&lt;&#x2F;p&gt;
&lt;p&gt;It rarely pays to be short sighted when choosing technologies for complex embedded systems.  The best strategy is to stay flexible and choose a platform with a future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gumstix Overo Connector Spreadsheet</title>
        <published>2008-12-15T00:00:00+00:00</published>
        <updated>2008-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/113/gumstix-overo-connector-spreadsheet/"/>
        <id>https://bec-systems.com/113/gumstix-overo-connector-spreadsheet/</id>
        
        <content type="html" xml:base="https://bec-systems.com/113/gumstix-overo-connector-spreadsheet/">&lt;p&gt;One of the first things I do when designing a system based on a processor module is create a spreadsheet listing all the connector I&#x2F;O.  This is the easiest way I’ve found to make sure nothing gets missed.  My first pass at a I&#x2F;O spreadsheet for the Gumstix Overo is available at:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;redmine.bec-systems.com&#x2F;bec&#x2F;documents&#x2F;1&quot;&gt;http:&#x2F;&#x2F;redmine.bec-systems.com&#x2F;bec&#x2F;documents&#x2F;1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to disable SSH host key checking</title>
        <published>2008-12-12T00:00:00+00:00</published>
        <updated>2008-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/220/how-to-disable-ssh-host-key-checking/"/>
        <id>https://bec-systems.com/220/how-to-disable-ssh-host-key-checking/</id>
        
        <content type="html" xml:base="https://bec-systems.com/220/how-to-disable-ssh-host-key-checking/">&lt;p&gt;This &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxcommando.blogspot.com&#x2F;2008&#x2F;10&#x2F;how-to-disable-ssh-host-key-checking.html&quot;&gt;article&lt;&#x2F;a&gt; presents a very nice overview of options to disable ssh host key checking.  When working with embedded systems where you are constantly reloading the rootfs, it is really annoying to have to edit your &lt;em&gt;~&#x2F;.ssh&#x2F;known_hosts&lt;&#x2F;em&gt;every time you update the rootfs on the target device.  The solution is to simply disable host key checking for your local subnet by adding something like the following to the beginning of &lt;em&gt;&#x2F;etc&#x2F;ssh&#x2F;ssh_config&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Host 192.168.1.*
   StrictHostKeyChecking no
   UserKnownHostsFile=&#x2F;dev&#x2F;null
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Anything not on the 192.168.1.* subnet is still checked.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2009-09-26:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Another place to put these config settings is: &lt;em&gt;~&#x2F;.ssh&#x2F;config&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Printing from Embedded Systems</title>
        <published>2008-12-02T00:00:00+00:00</published>
        <updated>2008-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/218/printing-from-embedded-systems/"/>
        <id>https://bec-systems.com/218/printing-from-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/218/printing-from-embedded-systems/">&lt;p&gt;How does one implement support for printing in embedded systems? I recently had the opportunity to add printing support to an embedded Linux system.  The device is an industrial touch screen powered by a Compulab cm-x270 module (PXA270 CPU), and runs a GTK+ application.  The customer is implementing a device calibration system where customers bring their equipment in to get calibrated, and the system prints out a report on a local printer.  This article describes how components of Hewlett Packard’s HPLIP solution along with Cairo can be used to implement printer support in a non-desktop Linux system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;&#x2F;h3&gt;
&lt;p&gt;The requirements for this project were fairly basic – we needed to print a single page report that contained text and some elementary graphics.  We initially wanted to support several low-end Inkjet and Laser USB printers.  As the system was powered by a fairly slow ARM processor (slow compared to modern desktop systems), the solution needed to be efficient, and not require excessive amounts of memory.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;desktop-linux-print-flow&quot;&gt;Desktop Linux Print Flow&lt;&#x2F;h3&gt;
&lt;p&gt;With desktop Linux systems, the standard printing flow looks something like this:&lt;&#x2F;p&gt;
&lt;p&gt;Application -&amp;gt; PS output -&amp;gt; Ghostscript -&amp;gt; Rasterized output -&amp;gt; Printer Driver (filter) -&amp;gt; I&#x2F;O Backend -&amp;gt; Printer&lt;&#x2F;p&gt;
&lt;p&gt;CUPS is typically used to manage this flow, provide queuing, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;print-architecture&quot;&gt;Print Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;As the application is written in GTK+, we decided to generate the report using Cairo, which is a 2D graphics library.  Cairo is easy to use, and is well suited for this application.  With a Cairo generated report, we already had a raster image of the report, so it seemed that the PS output&#x2F;Ghostscript steps were not really needed and only added more processing to the data flow.  Also the PXA270 CPU does not have a FPU, and PostScript processing can be floating point intensive.  So the need was now to figure out how to get a Cairo generated raster image to a USB printer.&lt;&#x2F;p&gt;
&lt;p&gt;Hewlett Packard offers lots of interesting software for their printers.  Their APDK is a OS independent library in source code form.  However, implementing this would have required quite a bit of integration, and writing the I&#x2F;O layer.  It seemed like there should be something available that would work with a little less effort.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;hplipopensource.com&#x2F;&quot;&gt;HPLIP project&lt;&#x2F;a&gt; is a comprehensive set of software for Linux printing, and is used by desktop Linux systems.  It is not obvious at a glance how all the components of HPLIP fit together, but after spending some time digging through source code, and asking questions on several maillists&#x2F;forums, we were able to figure out that the basic flow is:&lt;&#x2F;p&gt;
&lt;p&gt;Ghostscript -&amp;gt; HPIJS (driver) -&amp;gt; HP backend -&amp;gt; Printer&lt;&#x2F;p&gt;
&lt;p&gt;In this application, we simply launched the HPIJS driver directly from our application instead of Ghostscript.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hplip&quot;&gt;HPLIP&lt;&#x2F;h3&gt;
&lt;p&gt;There were several challenges using HPLIP in our ARM system.  The HPLIP is not cross-compilation friendly out of the box, so we had to fix a few issues, and ended up disabling all the Python pieces as we only needed the HPIJS and backend components.  We also had to figure out the data flow from the application to HPIJS, and then to HP backend.  In a nutshell, the process is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;start the hp backend process by forking, and obtain a file handle to STDIN for the hp backend process&lt;&#x2F;li&gt;
&lt;li&gt;start the HPIJS process, send various parameters to it including the file handle for the backend STDIN&lt;&#x2F;li&gt;
&lt;li&gt;send HPIJS the print raster and tell it to print&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are some additional details such as handling margins, error conditions, cancel support, etc.  Some of the details can be gleaned from the Ghostscript source code, and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.linuxprinting.org&#x2F;ijs&#x2F;&quot;&gt;IJS reference implementation&lt;&#x2F;a&gt; provides some very useful library code for implementing the IJS client functionality in the application that is doing the printing.  When finished, our printing module was 403 source lines of code (SLOC) – not bad considering the functionality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-well-does-it-work&quot;&gt;How well does it work?&lt;&#x2F;h3&gt;
&lt;p&gt;Overall, we are very pleased with the result.  With a simple industrial terminal, we can now support just about every USB printer made by HP with the exception of some of their very low end LaserJet printers that require a binary plugin.  The HP backend can be used to detect what printer is attached at run time, so everything is plug-n-play with &lt;em&gt;no&lt;&#x2F;em&gt; user configuration.  Let me repeat as this is significant – on a simple Industrial terminal, we can support about every HP USB printer available with no user configuration.  This is easier for users than their desktop as they simply need to buy a printer and plug it in!  Kudos to HP for their excellent open source software.  Because the source code is available, we were able to customize it for our application with very little support from HP.  Performance wise, the printing process is quite fast; the printer starts almost immediatly after the user initiates the print.  Now if I could just get HP to build a ARM version of their binary plugin for the few low end lasers we can’t support … but this is not a critical issue for this vertical application.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;future-direction&quot;&gt;Future Direction&lt;&#x2F;h3&gt;
&lt;p&gt;Hopefully, this type of solution can evolve into a standard printing solution for Embedded Linux systems.  Epson also supports the IJS driver model, so adding support for their printers should be possible.  It may eventually make sense to integrate portions of CUPS for queing, and other management tasks.  Some of the tasks I hope to implement in the future:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clean up the HPLIP build for inclusion in OpenEmbedded.&lt;&#x2F;li&gt;
&lt;li&gt;Clean up the IJS reference code library build and packaging in OpenEmbedded.&lt;&#x2F;li&gt;
&lt;li&gt;Figure out portions of CUPS that may make sense.&lt;&#x2F;li&gt;
&lt;li&gt;Keep conversations going with the Linux printing group so we can someday have a “standard” printing solution for embedded Linux systems.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Thanks to Matt Gessner for helping implement this solution, and for providing feedback on this article.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Things that work!</title>
        <published>2008-11-19T00:00:00+00:00</published>
        <updated>2008-11-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/250/things-that-work/"/>
        <id>https://bec-systems.com/250/things-that-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/250/things-that-work/">&lt;p&gt;Running a small business has a special set of challenges, and if you are not careful, the overhead can quickly consume you.  This article is a list of things that I use in my business that work well for me, and help me to be efficient when there is so much to do …&lt;&#x2F;p&gt;
&lt;p&gt;Entire article at: &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;101&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;101&#x2F;9&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;asterisk&quot;&gt;Asterisk&lt;&#x2F;h3&gt;
&lt;p&gt;While I can’t say the same for VOIP proiders, the Asterisk PXB is a very solid product.  I run it on an ancient 1GHz celeron system, and use it for my office PBX.  In combination with a VOIP service, I can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;handle multiple calls at once&lt;&#x2F;li&gt;
&lt;li&gt;easily conference multiple callers&lt;&#x2F;li&gt;
&lt;li&gt;forward calls to my cell phone or other numbers&lt;&#x2F;li&gt;
&lt;li&gt;provide extensions for associates who are working with me&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;and all at a very low cost.  To mitigate some of the reliability problems I’ve had with VOIP providers, I set the VOIP provider to use my cell phone as a backup if the VOIP link is down.  I also use multiple VOIP providers for outgoing calls so that if one is not working, I can usually use the backup.  Overall, I really like the features, and for my business the occasional hassle is worth it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sql-ledger&quot;&gt;SQL-Ledger&lt;&#x2F;h3&gt;
&lt;p&gt;SQL-Ledger is a web based accounting program that is open source.  It provides all the features I need to run my business, and offers the following advantages over more traditional programs such as Quickbooks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;web based so I can access it anywhere, even remotely.&lt;&#x2F;li&gt;
&lt;li&gt;subcontractors and associates can log time remotely directly in my accounting system.&lt;&#x2F;li&gt;
&lt;li&gt;granular permissions for different people who need to use it.&lt;&#x2F;li&gt;
&lt;li&gt;upgrades just work.&lt;&#x2F;li&gt;
&lt;li&gt;consistent, reliable operation that I expect from an accounting system.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;openocd&quot;&gt;OpenOCD&lt;&#x2F;h3&gt;
&lt;p&gt;We finally have a low cost, open source JTAG solution that works reasonably well.  While there are still issues, it gets the job done for most of my projects, and offers my customers a low cost way to program their systems using JTAG.  Often customers are not doing extensive development, and it is nice to be able to provide a solution for the occasional need.  One customer fought with a very expensive commercial unit for weeks.  I finally shipped them a $50 Olimex unit that did everything they needed.  There can’t be enough said for everyone on a team using the same tools, and they only way this can happen easily is if the tools are fairly low cost.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tracks&quot;&gt;Tracks&lt;&#x2F;h3&gt;
&lt;p&gt;Tracks is a nice web-based task managment tool to help implement the GTD methodology.  The user interface is supurb and better than most native applications I’ve used.  I use the “starred” items for my “next action” on each project.  Very nice!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;printable-ceo-emergent-time-tracker&quot;&gt;Printable CEO Emergent Time Tracker&lt;&#x2F;h3&gt;
&lt;p&gt;I use David Seah’s handy &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;davidseah.com&#x2F;blog&#x2F;the-printable-ceo-iii-emergent-task-timing&#x2F;&quot;&gt;form&lt;&#x2F;a&gt; for tracking my time during the day.  It forces me to use a pen and paper every day which is a pretty rare thing, and is a nice compromise between simplicity and automation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openembedded&quot;&gt;OpenEmbedded&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve written a lot about the &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&quot;&gt;benefits&lt;&#x2F;a&gt; of OpenEmbedded.  It makes the huge task of creating a build system for Embedded Linux systems very manageable and repeatable.  When build systems are fully automated, things are so much easier.  As an example, I’ve been working on one project for over two years, and have built 313 releases.  We have had almost no image failures due to forgetting to put something in the image, or some other manual step you tend to find in build systems.  This is the power of a fully automated build system with _no_ manual steps.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ubuntu&quot;&gt;Ubuntu&lt;&#x2F;h3&gt;
&lt;p&gt;Once I become convinced that Ubuntu could do distro upgrades, I finally quit using Gentoo.  Between servers, workstations, and home computers, I now maintain about 10 Ubuntu systems.  Over the past several years, I’ve had very few problems using the distro upgrade mechanism.  Also, the fact that Ubuntu includes fairly recent Linux technology is a big plus for experimenting with components I use in embedded Linux systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dhl-ups-pickup&quot;&gt;DHL&#x2F;UPS Pickup&lt;&#x2F;h3&gt;
&lt;p&gt;Working from a small office where I do not regularly make shipments, it is really convenient to be able to schedule a pickup with shipping companies like DHL and UPS.   This can be done over the web in 15 minutes or so, and a shipping label then prints out on your printer.  The DHL website will also provide commercial invoices for overseas shipping.  This sure beats driving to the local UPS shipping place, filling out paper work with a pen, waiting in line, etc.  Just another thing that makes it easier for a small business to run efficiently.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;intel-bare-bones-server&quot;&gt;Intel Bare Bones Server&lt;&#x2F;h3&gt;
&lt;p&gt;Last year, I was looking for a cost effective 1U rack server.  I selected a Intel SR1530 Bare Bones server.  I installed it over a year ago and have not touched it since.  Last time I checked, the uptime was 254 days.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-ware-raid-controllers&quot;&gt;3-ware Raid Controllers&lt;&#x2F;h3&gt;
&lt;p&gt;(I guess it is AMCC now …) They just work with Linux – currently running in two systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sandusky-cabinets&quot;&gt;Sandusky Cabinets&lt;&#x2F;h3&gt;
&lt;p&gt;Doing embedded system development means I get a lot of equipment from customers.  As some of the development stretches over several years with occasional ongoing support, its nice to be able to store this equipment and then find it efficiently. I’ve found the “Sandusky Standard Storage Cabinets” from Staples to work very well.  They are fairly cheap, yet durable enough for what I need, and keeps everything enclosed which looks neat, and keeps the dust problem under control.  And, Staples offers free delivery.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bob-pease-organization-system&quot;&gt;Bob Pease organization system&lt;&#x2F;h3&gt;
&lt;p&gt;Bob Pease had an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;electronicdesign.com&#x2F;Articles&#x2F;Index.cfm?ArticleID=5385&quot;&gt;article&lt;&#x2F;a&gt; in Electronic Design some time ago about organizing things in his refrigerator.  He used small boxes to group things in his refrigerator.  I use the same method in my Sandusky cabinets and it makes it very easy to find something when I need it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_1-1.jpg&quot; alt=&quot;work_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gtd-labeling-system&quot;&gt;GTD Labeling System&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve slowing been adopting some of David Allen’s organization ideas from “Getting Things Done”.  One of his best ideas is to get a labeller.  I used to use a Brother handheld labeller, but lately, I’ve been using a Dymo LabelWriter 400 left over from a project.  The LabelWriter connects to your computer via USB, works well with Linux, and allows me to use my standard keyboard, and OpenOffice to create labels.  Note, the labels on the boxes in the above picture.  The high contrast black on white makes it much easier to find things versus hand writing notes on cardboard boxes, file folders, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gtd-filing-system&quot;&gt;GTD Filing System&lt;&#x2F;h3&gt;
&lt;p&gt;I used to use hanging file folders, but no more.  David Allen’s suggestion of simply using plain manila file folders with nice labels works very well. Once again the large, high contrast labels makes it easy to find things.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_2-1.jpg&quot; alt=&quot;work_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;snaketray-cable-management&quot;&gt;Snaketray Cable Management&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve already written about &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;73&#x2F;9&#x2F;&quot;&gt;my cable management system&lt;&#x2F;a&gt;.  A year later, I still like it and no longer dread digging through cables.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;steelcase-leap-chair&quot;&gt;Steelcase Leap Chair&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve sat in various chairs over the years – mostly the cheap office store variety that most companies buy. I must be getting old enough now that they no longer cut it.  I tried a Herman Miller Aeron for a week as that is what everyone recommends, but I found it too hard.  I then tried a Steelcase Leap chair and it works great for me.  I no longer even think about the chair I’m sitting in, even after a long day.  Expensive, but well worth it if you spend as much time sitting as I do.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tomboy-notes-gnome-do&quot;&gt;Tomboy Notes + gnome-do&lt;&#x2F;h3&gt;
&lt;p&gt;Tomboy notes is a Linux desktop note-taking application that is essentially a personal wiki.  It automatically tracks links to other pages, links to file locations, etc and organization is done mostly through links instead of hierarchy.  It is simply the best note taking system I have ever used.  Coupled with gnome-do, I can instantly bring up any note with only a few keystrokes.  In this day and age where information abounds, being able to take and recall notes efficiently is critical to being effective.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;konsole&quot;&gt;Konsole&lt;&#x2F;h3&gt;
&lt;p&gt;Being able to easily name the tabs in the KDE console application is very handy as I’ll typically have 5-10 named consoles going at one time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_3-1.png&quot; alt=&quot;work_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;8-port-usb-serial-expander&quot;&gt;8-port USB serial expander&lt;&#x2F;h3&gt;
&lt;p&gt;As I work with a lot of different devices, it is very handy to have lots of serial ports available.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.usbgear.com&#x2F;USB2-8COM-M.html&quot;&gt;SerialGear device&lt;&#x2F;a&gt; available from http:&#x2F;&#x2F;www.usbgear.com works out of the box with modern Linux distributions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_4-1.jpg&quot; alt=&quot;work_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;git&quot;&gt;Git&lt;&#x2F;h3&gt;
&lt;p&gt;I’m starting to really appreciate the benefits of distributed source control systems.  For commercial embedded development, it allows me to easily track upstream projects, yet have a local source control system for tracking project changes.  Having everything in one version control system makes it much easier to extract patches to push back upstream, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;redmine&quot;&gt;Redmine&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve been a happy &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;trac.edgewall.org&#x2F;&quot;&gt;trac&lt;&#x2F;a&gt; user for years, but have recently switched to using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.redmine.org&#x2F;&quot;&gt;Redmine&lt;&#x2F;a&gt; for project management.  Redmine offers some addition features such as multiple project support, and the user interface is a little more polished.  As all of my projects are accomplished with distributed teams, it is very important that there be clear visibility as to what is going on in the project.  It also helps to give customers the “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&quot;&gt;Warm Fuzzy Feeling&lt;&#x2F;a&gt; TM” as they have clear visibility into the project, and they can easily verify there is progress being made on the project.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Benefits of OpenEmbedded switching to Git</title>
        <published>2008-10-22T00:00:00+00:00</published>
        <updated>2008-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/216/benefits-of-openembedded-switching-to-git/"/>
        <id>https://bec-systems.com/216/benefits-of-openembedded-switching-to-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/216/benefits-of-openembedded-switching-to-git/">&lt;p&gt;Recently the OpenEmbedded project has switched to the Git version control system.  This is good news for many reasons.  The obvious reasons are Git is faster than Monotone, handles branching better, has lots of nice features, larger user base, etc.  Monotone has served us well, but as new tools become available, it is time to change.  For those of us helping customers use OE for embedded projects, Git will make using OE much easier.  Companies want to be able to track OE with minimal effort and typically maintain a few minor tweaks to OE.  As most Embedded Linux projects now implement Git infrastructure for kernel development, the OE source tree can be maintained using the same infrastructure.  Branching is very natural in Git, so it is fairly easy to create a OE “topic branch” and periodically merge with upstream changes as needed.  The ability for easy repo hosting and branching allows OE users to lock down a version of OE for periods of project development, and still maintain a connection to the upstream OE repository for easily updating to new versions, or cherrypicking changes.  So a big thank you to all who helped make this change happen.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>more fun with git branches</title>
        <published>2008-08-26T00:00:00+00:00</published>
        <updated>2008-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/213/more-fun-with-git-branches/"/>
        <id>https://bec-systems.com/213/more-fun-with-git-branches/</id>
        
        <content type="html" xml:base="https://bec-systems.com/213/more-fun-with-git-branches/">&lt;p&gt;One thing you learn after using git for awhile is you get used to trying random things, and it will often just work.  For example, if I want to know the differences between Linus’s kernel tree, and the Wolfson dev branch for a particular directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;build&#x2F;linux-2.6$ git diff --stat origin&#x2F;master..wolfson&#x2F;dev sound&#x2F;soc&#x2F;codecs
 sound&#x2F;soc&#x2F;codecs&#x2F;Kconfig       |  125 +++
 sound&#x2F;soc&#x2F;codecs&#x2F;Makefile      |   34 +
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1939.c      |  690 +++++++++++++++
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1939.h      |   70 ++
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1980.c      |  309 +++++++
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1980.h      |   23 +
 sound&#x2F;soc&#x2F;codecs&#x2F;cs4251x.c     |  771 +++++++++++++++++
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another way to get similar information is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git log origin&#x2F;master..wolfson&#x2F;dev sound&#x2F;soc&#x2F;codecs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If I’m working on a topic branch, and I want to see a summary of all the changes in my Topic branch:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git log --stat origin&#x2F;master..origin&#x2F;my_topic_branch &amp;gt; my_topic_branch_changelog.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One of the neat things about git branches is you don’t have to be on a branch to interact with it.  You can diff, log, and checkout from branches other than the one you are currently in, and it is all very fast.  For instance, if I want to grab the latest copy of a file in the Wolfson dev branch, I can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git log checkout wolfson&#x2F;dev sound&#x2F;soc&#x2F;codecs&#x2F;wm9713.c
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not that this is a very good idea, but just to illustrate a point.  Git branches are amazing and make development work so much less tedious.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux Input Testing and Debugging</title>
        <published>2008-08-22T00:00:00+00:00</published>
        <updated>2008-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/209/linux-input-testing-and-debugging/"/>
        <id>https://bec-systems.com/209/linux-input-testing-and-debugging/</id>
        
        <content type="html" xml:base="https://bec-systems.com/209/linux-input-testing-and-debugging/">&lt;p&gt;The Linux input layer has made a lot of progress in recent years.  When writing a new input driver (such as keyboard, trackball, etc), it is useful to be able to monitor input events using a test application.  This article describes two ways to accomplish this using kernel input debugging, and the evtest utility.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kernel-input-debugging&quot;&gt;kernel input debugging&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux kernel includes some support for printing input events as debug messages.  To use, set the following in the kernel config:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_INPUT_EVBUG=y
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because the print messages are at the KERN_DEBUG level (7), we typically need to change the debug level:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;echo 8 &amp;gt; &#x2F;proc&#x2F;sys&#x2F;kernel&#x2F;printk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, you will see messages like the following on the console:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 108, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 103, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 106, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 103, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 103, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 1
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 1
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;evtest&quot;&gt;evtest&lt;&#x2F;h3&gt;
&lt;p&gt;The linux-input project (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxconsole.sourceforge.net&#x2F;input&#x2F;input.html&quot;&gt;http:&#x2F;&#x2F;linuxconsole.sourceforge.net&#x2F;input&#x2F;input.html&lt;&#x2F;a&gt;) includes a neat little tool named evtest that is very handy for testing input devices.  If you are using OpenEmbedded, simply:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bitbake linux-input
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you are not using OpenEmbedded, you can glean enough details about how to get and build the this package from the OE recipe:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gitweb.openembedded.net&#x2F;?p=org.openembedded.dev.git;a=blob;f=packages&#x2F;linux-input&#x2F;linux-input_cvs.bb&quot;&gt;http:&#x2F;&#x2F;gitweb.openembedded.net&#x2F;?p=org.openembedded.dev.git;a=blob;f=packages&#x2F;linux-input&#x2F;linux-input_cvs.bb&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Install the resulting package on your device.   To use, run evtest with a &#x2F;dev&#x2F;input&#x2F;eventx argument:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@machine1:~$ evtest &#x2F;dev&#x2F;input&#x2F;event0
Input driver version is 1.0.0
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: &amp;quot;gpio-keys&amp;quot;
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 103 (Up)
    Event code 105 (Left)
    Event code 106 (Right)
    Event code 108 (Down)
    Event code 116 (Power)
Testing ... (interrupt to exit)
Event: time 1009.433605, type 1 (Key), code 108 (Down), value 0
Event: time 1009.433737, -------------- Report Sync ------------
Event: time 1010.735605, type 1 (Key), code 108 (Down), value 1
Event: time 1010.735740, -------------- Report Sync ------------
Event: time 1011.075586, type 1 (Key), code 106 (Right), value 1
Event: time 1011.075720, -------------- Report Sync ------------
Event: time 1011.103379, type 1 (Key), code 108 (Down), value 0
Event: time 1011.103550, -------------- Report Sync ------------
Event: time 1011.333924, type 1 (Key), code 108 (Down), value 1
Event: time 1011.334058, -------------- Report Sync ------------
Event: time 1011.339880, type 1 (Key), code 106 (Right), value 0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that evtest lists the keymap when it is initially run which is very handy, and then lists key events as they occur.  The key descriptions are also included with events so you don’t have to manually decode the keycodes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using a Verizon USB720 modem in an Embedded Linux system</title>
        <published>2008-06-02T00:00:00+00:00</published>
        <updated>2008-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/203/using-a-verizon-usb720-modem-in-an-embedded-linux-system/"/>
        <id>https://bec-systems.com/203/using-a-verizon-usb720-modem-in-an-embedded-linux-system/</id>
        
        <content type="html" xml:base="https://bec-systems.com/203/using-a-verizon-usb720-modem-in-an-embedded-linux-system/">&lt;p&gt;&lt;img src=&quot;file:&#x2F;&#x2F;&#x2F;tmp&#x2F;moz-screenshot.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Verizon USB720 Cellular modem is a quick and easy way to add wireless internet connectivity to your embedded system.  Why might you want to add cellular  connectivity to your embedded device?  Remote access and diagnostics is a big reason.  One customer I have is planning to supply all their distributors with a USB720 so they can easily upload log files from devices in the field.  The alternative is copying the log files to a flash drive, finding a PC connected to the internet, and then uploading the files – too much hassle, therefore it does not get done.  Also, think about the cost of sending a field support person on-site to troubleshoot problems versus shipping them a USB720 and accessing the device remotely.&lt;&#x2F;p&gt;
&lt;p&gt;The USB720 is a fairly small device that plugs into the ubiquitous USB port.  This articles covers some of the details on how to configure an embedded Linux system to work with this device.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-is-the-usb720-a-good-fit-for-wireless-connectivity-in-embedded-systems&quot;&gt;Why is the USB720 a good fit for wireless connectivity in Embedded Systems?&lt;&#x2F;h3&gt;
&lt;p&gt;Some reasons the USB720 (or other USB based cellular modems) is an attractive option:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;fairly fast: provides typical download speeds of 600-1400kbps, and upload speeds of 500-800kbps&lt;&#x2F;li&gt;
&lt;li&gt;convenience: it plugs into a USB port.  No taking apart the box and installing an embedded module, etc.&lt;&#x2F;li&gt;
&lt;li&gt;affordable: with plans around $60&#x2F;mo, its a lot cheaper than sending field support people on-site to debug every problem.&lt;&#x2F;li&gt;
&lt;li&gt;uses standard PPP protocols for connection.  That means it works with Linux.&lt;&#x2F;li&gt;
&lt;li&gt;supported by the mainstream Linux kernel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;usb720_a-1.jpg&quot; alt=&quot;usb720_a&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kernel-configuration&quot;&gt;Kernel Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;The USB720 looks like a USB-serial device to the host system.  If you plug it into your Ubuntu desktop Linux system, all the needed kernel pieces are there and it will just work.  With your embedded system, you need to make sure a number of kernel options are enabled including:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_PPP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_DEFLATE=m
CONFIG_SLHC=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_OPTION=m
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The CONFIG_USB_SERIAL_OPTION selection enables a driver that is specifically optimized to work with the USB chip found in many cellular modems.  Once you enable the above modules, and if you are running udev, simply plugging in the device will cause the appropriate modules to load and a &#x2F;dev&#x2F;ttyUSB0 device will now appear.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ppp-scripts&quot;&gt;PPP Scripts&lt;&#x2F;h3&gt;
&lt;p&gt;The most difficult part of this exercise is figuring out how to configure the PPP scripts.  Verizon of course does not tell you how to configure their device and only supplies software for Windows and MAC.  There are a number of howtos available on the internet, but most of them are tailored to using kppp or wvdial. Neither are very practical for embedded systems. Fortunately, the standard pppd daemon is fairly easy to use, is easy to build for embedded systems (it is already included in OpenEmbedded), and seems to work very well.  The following scripts are needed:&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;noauth
connect &amp;quot;&#x2F;usr&#x2F;sbin&#x2F;chat -v -f &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_chat&amp;quot;
defaultroute
usepeerdns
ttyUSB0
921600
local
usepeerdns
debug
-detach
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_chat&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#39;&amp;#39; &amp;#39;ATZ&amp;#39;
&amp;#39;OK&amp;#39; &amp;#39;ATDT#777&amp;#39;
&amp;#39;CONNECT&amp;#39; &amp;#39;&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;ppp&#x2F;chap-secrets
&#x2F;etc&#x2F;ppp&#x2F;pap-secrets&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;&amp;lt;phone number&amp;gt;@vzw3g.com&amp;quot;  *       &amp;quot;vzw&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, you can run &lt;em&gt;pppd call verizon&lt;&#x2F;em&gt; and you should see something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; root@cm-x270:~$ pppd call verizon
Serial connection established.
using channel 9
Using interface ppp0
Connect: ppp0 &amp;lt;--&amp;gt; &#x2F;dev&#x2F;ttyUSB0
Warning - secret file &#x2F;etc&#x2F;ppp&#x2F;pap-secrets has world and&#x2F;or group access
sent [LCP ConfReq id=0x1 &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0x539657b7&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
rcvd [LCP ConfReq id=0x0 &amp;lt;mru 1500&amp;gt; &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0xb9b652e5&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
sent [LCP ConfAck id=0x0 &amp;lt;mru 1500&amp;gt; &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0xb9b652e5&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
rcvd [LCP ConfAck id=0x1 &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0x539657b7&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
sent [CCP ConfReq id=0x1 &amp;lt;deflate 15&amp;gt; &amp;lt;deflate(old#) 15&amp;gt;]
sent [IPCP ConfReq id=0x1 &amp;lt;compress VJ 0f 01&amp;gt; &amp;lt;addr 192.168.1.119&amp;gt; &amp;lt;ms-dns1 0.0.0.0&amp;gt; &amp;lt;ms-dns3 0.0.0.0&amp;gt;]
rcvd [LCP DiscReq id=0x1 magic=0xb9b652e5]
rcvd [LCP ProtRej id=0x2 80 fd 01 01 00 0c 1a 04 78 00 18 04 78 00]
rcvd [IPCP ConfReq id=0x0 &amp;lt;addr 66.174.61.4&amp;gt;]
sent [IPCP ConfAck id=0x0 &amp;lt;addr 66.174.61.4&amp;gt;]
rcvd [IPCP ConfRej id=0x1 &amp;lt;compress VJ 0f 01&amp;gt;]
sent [IPCP ConfReq id=0x2 &amp;lt;addr 192.168.1.119&amp;gt; &amp;lt;ms-dns1 0.0.0.0&amp;gt; &amp;lt;ms-dns3 0.0.0.0&amp;gt;]
rcvd [IPCP ConfNak id=0x2 &amp;lt;addr 70.210.82.191&amp;gt; &amp;lt;ms-dns1 66.174.95.44&amp;gt; &amp;lt;ms-dns3 66.174.92.14&amp;gt;]
sent [IPCP ConfReq id=0x3 &amp;lt;addr 70.210.82.191&amp;gt; &amp;lt;ms-dns1 66.174.95.44&amp;gt; &amp;lt;ms-dns3 66.174.92.14&amp;gt;]
rcvd [IPCP ConfAck id=0x3 &amp;lt;addr 70.210.82.191&amp;gt; &amp;lt;ms-dns1 66.174.95.44&amp;gt; &amp;lt;ms-dns3 66.174.92.14&amp;gt;]
not replacing default route to eth0 [192.168.1.1]
local  IP address 70.210.82.191
remote IP address 66.174.61.4
primary   DNS address 66.174.95.44
secondary DNS address 66.174.92.14
Script &#x2F;etc&#x2F;ppp&#x2F;ip-up started (pid 2303)
Script &#x2F;etc&#x2F;ppp&#x2F;ip-up finished (pid 2303), status = 0x0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ ifconfig
ppp0      Link encap:Point-to-Point Protocol
          inet addr:70.210.82.191  P-t-P:66.174.61.4  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:64 (64.0 B)  TX bytes:94 (94.0 B)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You are connected :-)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-the-oe-ppp-package&quot;&gt;Using the OE ppp package&lt;&#x2F;h3&gt;
&lt;p&gt;Add ppp support to your image using OE is fairly straightfoward:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;add the kernel modules to your image&lt;&#x2F;li&gt;
&lt;li&gt;add&lt;em&gt;ppp&lt;&#x2F;em&gt; to your image&lt;&#x2F;li&gt;
&lt;li&gt;add a custom package that includes the configuration scripts listed above&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One thing that may trip you up is the ppp scripts are expecting resolv.conf to be in the following location: &#x2F;var&#x2F;run&#x2F;resolv.conf.  The reason for this is we want resolv.conf in a RAM file system to prevent unneeded flash wear.  Therefore, &#x2F;etc&#x2F;resolv.conf should be configured in your rootfs as a soft link to &#x2F;var&#x2F;run&#x2F;resolv.conf.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux kernel support for USB720 and the pppd package offer a quick, robust way to add cellular network connectivity to about any embedded Linux system that has a USB host port.  As systems become more complex, it will be increasingly important to be able to remotely access systems in the field to troubleshoot problems, help users with configuration, etc.  The USB720 offers a quick way to provide this type of connection without going through the expense of designing cellular connectivity into your product.  One thing I usually encourage all my customers to do when designing new products is expose a USB host port, even though they may not see any immediate use for it.  This is one of those reasons.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a picture of a USB720 connected to a Compulab cm-x270 development system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;usb720_b-1.jpg&quot; alt=&quot;usb720_b&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Autotools quick reference</title>
        <published>2008-05-03T00:00:00+00:00</published>
        <updated>2008-05-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/121/autotools-quick-reference/"/>
        <id>https://bec-systems.com/121/autotools-quick-reference/</id>
        
        <content type="html" xml:base="https://bec-systems.com/121/autotools-quick-reference/">&lt;p&gt;At some point, most Linux developers need to master Autotools.  For most of us, this is a fairly painful process, but like any good tool, Autotools is extremely useful and well worth learning.  For example, if your program is set up correctly using Autotools, it will cross compile with almost zero effort in OpenEmbedded, or with slight effort manually.  Compare this to the tedious effort of manually referencing toolchain locations, cross toolchain library and header file locations, etc.  Despite first impressions, Autotools will make your life easier.  This article contains a collection of tips on how to do standard operations using Autotools.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minimal-autotools-files-required-for-a-simple-c-application&quot;&gt;Minimal Autotools files required for a simple C application&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;configure.ac&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AC_INIT([fooprog], [1.0], [email@company.com])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC

AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bin_PROGRAMS = foo
foo_SOURCES = foo.c
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above files will create a binary name foo (compiled from foo.c) when you run the following steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;touch NEWS AUTHORS ChangeLog&lt;&#x2F;li&gt;
&lt;li&gt;autoreconf -i&lt;&#x2F;li&gt;
&lt;li&gt;.&#x2F;configure&lt;&#x2F;li&gt;
&lt;li&gt;make&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;how-to-add-libraries-to-the-link-step&quot;&gt;How to add libraries to the link step&lt;&#x2F;h2&gt;
&lt;p&gt;For example, if you want to link in the pthread library to your application, add the following line to Makefile.am:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo_LDADD = -lpthread
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-to-add-compiler-options&quot;&gt;How to add compiler options&lt;&#x2F;h2&gt;
&lt;p&gt;You can easily add compiler options using the foo_CFLAGS or foo_CPPFLAGS variables.&lt;&#x2F;p&gt;
&lt;p&gt;foo_CFLAGS = -DMY_DEFINE&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-use-pkg-config-in-autotools&quot;&gt;How to use pkg-config in Autotools&lt;&#x2F;h2&gt;
&lt;p&gt;pkg-config is a helper tool that gives you library and include file information for various libraries installed.  For example, to link to alsa and glib in your project:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;configure.ac&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;PKG_CHECK_MODULES(PACKAGE, alsa glib-2.0)
AC_SUBST(PACKAGE_CFLAGS)
AC_SUBST(PACKAG_LIBS)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo_CFLAGS = @PACKAGE_CFLAGS@
foo_LDADD = @PACKAGE_LIBS@
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-to-add-a-command-line-option-to-the-configure-script&quot;&gt;How to add a command line option to the configure script&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;AC_ARG_ENABLE(option-foo,
    [  --enable-option-foo  help for option foo],
    [CFLAGS=&amp;quot;$CFLAGS -DOPTION_FOO_DEFINE&amp;quot;], [])
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above example sets a define on the compiler command line if configure is run with the &lt;em&gt;--enable-option-foo&lt;&#x2F;em&gt; command line option.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disable-shared-libraries-in-your-project&quot;&gt;Disable shared libraries in your project&lt;&#x2F;h2&gt;
&lt;p&gt;Add the following to configure.ac:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AC_DISABLE_SHARED
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pass-a-variable-from-configure-ac-to-makefile-am&quot;&gt;Pass a variable from configure.ac to Makefile.am&lt;&#x2F;h2&gt;
&lt;p&gt;Often there is a need to pass a variable in configure.ac to a Makefile.  This is done with the AC_SUBST macro:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;configure.ac&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AC_SUBST(VAR_FOO)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;foo2 = @VAR_FOO@&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-data-files&quot;&gt;Installing data files&lt;&#x2F;h2&gt;
&lt;p&gt;By default, Autotools will install executables built when you run “make install”.  To install other non-executable files, you need to tell autotools explicitly about those files.  The standard place to install data files for an application is in $(datadir)&#x2F;appname.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;fooextradir = $(datadir)&#x2F;@PACKAGE@
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;fooextra_DATA = \
	foo_data1.txt \
	foo_data2.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above will install the &lt;em&gt;foo_data1.txt&lt;&#x2F;em&gt; and &lt;em&gt;foo_data2.txt&lt;&#x2F;em&gt; files in the &lt;em&gt;$(datadir)&#x2F;fooprog&lt;&#x2F;em&gt; directory. $(datadir) is typically &#x2F;usr&#x2F;share&#x2F; or &#x2F;usr&#x2F;local&#x2F;share, but it can be anything.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-does-my-program-know-where-datadir-is-located&quot;&gt;How does my program know where $(datadir) is located&lt;&#x2F;h2&gt;
&lt;p&gt;Because $(datadir) can be anywhere in the system, we need some way to tell the program where it was specified to be at time of compilation so that it can locate foo_data1.txt and foo_data2.txt.  This can be done by passing a define at compile time:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AM_CFLAGS = -DDATADIR=\&amp;quot;$(datadir)\&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-to-install-data-files-during-development-without-cluttering-up-my-system-directories&quot;&gt;How to install data files during development without cluttering up my system directories&lt;&#x2F;h2&gt;
&lt;p&gt;If you use the above method to install data files needed by your project, you may run into a case during development where you want to run the program from the build directory, but the program needs the data files at run time.  Since, the program is looking for them in the location specified by the DATADIR define, they need to be installed.  You could just run “make install”, but this would install them into &#x2F;usr&#x2F;local&#x2F;share, require you to run as root, and clutter up your system directories.  A much more elegant solution is to specify the install prefix at configure time to be a temporary “install” directory in your source tree.  The --prefix option for configure requires an absolute directory, so the `pwd` trick is used to figure out what the current directory is.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;.&#x2F;configure --prefix=`pwd`&#x2F;install
make install
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your project will now be installed in a directory in your source tree named .&#x2F;install.  This is also a nice way to test that the install for the project is working correctly as you can easily see everything that gets installed.  Now, the program has been compiled to reference extra files in .&#x2F;install and will run just fine from the build directory.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Linux kernel container_of macro</title>
        <published>2008-04-02T00:00:00+00:00</published>
        <updated>2008-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/115/the-linux-kernel-container_of-macro/"/>
        <id>https://bec-systems.com/115/the-linux-kernel-container_of-macro/</id>
        
        <content type="html" xml:base="https://bec-systems.com/115/the-linux-kernel-container_of-macro/">&lt;p&gt;The Linux kernel contains a very useful macro named “container_of” that is used extensively in back-casting a data structure to its containing data structure.  This article includes a simple program that illustrates how this macro is used, and explains why it is so useful.&lt;&#x2F;p&gt;
&lt;p&gt;If you do a lot of C programming, this program is worth figuring out :-).&lt;&#x2F;p&gt;
&lt;p&gt;The program source can also be downloaded from the following location: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;container_of&#x2F;linux_container_of_example.c&quot;&gt;&#x2F;linux&#x2F;linux_container_of_example.c&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;* test code to illustrate use of Linux kernel container_of macro
 *
 * Copyright (c) 2008 Cliff Brake, BEC Systems LLC
 *
 * This program is free software; you can redistribute it and&#x2F;or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *&#x2F;

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

&#x2F;* This program illustrates how the container_of macro works.
 * The container of macro is very useful in multi layered
 * software systems where you have progressivly more detailed
 * software layers.  Below is an example of a bus layer,
 * and then a device layer where a number of different
 * devices might register with the bus.
 * The device registers itself with the bus subsystem, and
 * then the bus subsystem makes a callback into the device.
 * Normally if there are multiple devices registered, the
 * bus subsystem must store and pass a device structure
 * when making callbacks.  With the container_of macro, this is
 * no longer necessary, and the bus subsystem only has to
 * know about one generic device structure, and does not need visibility
 * into lots of different device structures, or do tricks
 * by casting void pointers, etc.  With the container_of macro
 * we can backcast from the generic data structure, to the containing
 * datastructure.  This forces good separation of code in that
 * that bus layer cannot modifiy data structures that are specific
 * to the device layer.
 *
 *&#x2F;

&#x2F;**
 * (from Linux kernel source)
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:	the pointer to the member.
 * @type:	the type of the container struct this is embedded in.
 * @member:	the name of the member within the struct.
 *
 *&#x2F;
#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)-&amp;gt;member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &amp;amp;((TYPE *)0)-&amp;gt;MEMBER)

&#x2F;*==========================================================
 * BUS layer code
 *==========================================================*&#x2F;

&#x2F;* generic bus device structure *&#x2F;
struct bus_device
{
	int general_device_param_a;
	int general_device_param_b;
	void (*device_callback)(struct bus_device * bd);
};

&#x2F;* the following is a global list of
 * devices that have registered with the
 * bus subsystem.  Normally this would
 * be something like a dynamic linked list.
 *&#x2F;
struct bus_device * bd_list[5];

&#x2F;* function to register a device with the bus *&#x2F;
void register_with_bus(struct bus_device * bd)
{
	&#x2F;* since this example only deals with one
	 * device, will put it in slot 0
	 *&#x2F;

bd_list[0] = bd;
}

void start_bus()
{
	int i;
	struct bus_device * bd;

&#x2F;* make callbacks to all devices on bus *&#x2F;
	for (i=0;i&amp;lt;sizeof(bd_list)&#x2F;sizeof(bd_list[0]);i++) {
		bd = bd_list[i];
		if (!bd) continue;
		&#x2F;* call device callback with generic
		 * bus device structure
		 *&#x2F;
		bd-&amp;gt;device_callback(bd);
	}
}

&#x2F;*==========================================================
 * device X specific code
 * this would normally be in a different module
 *==========================================================*&#x2F;

&#x2F;* structure that holds device X specific stuff, as well as
 * generic bus_device structure
 *&#x2F;
struct device_x
{
	int device_x_specific_param_a;
	int device_x_specific_param_b;
	struct bus_device bd;
};

void device_x_callback(struct bus_device * bd)
{
	&#x2F;* if we know the structure type that contains the bus_device structure,
	 * we can extract a pointer to the containing structure using the container_of
	 * macro
	 *&#x2F;

&#x2F;*                                   ptr       type       member  *&#x2F;
	struct device_x * devx = container_of(bd, struct device_x, bd);

&#x2F;* the above statement expands to
	 * struct device_x * devx = (
	 * {
	 *   const typeof( ((struct device_x *)0)-&amp;gt;bd ) *__mptr = (bd);
	 *   (struct device_x *)( (char *)__mptr - ((size_t) &amp;amp;((struct device_x *)0)-&amp;gt;bd) );
	 * }
	 * );
	 *&#x2F;

printf(&amp;quot;device_x_callback called!, device_x_specific_param_a = %i\n&amp;quot;,
			devx-&amp;gt;device_x_specific_param_a);
}

void device_x_init()
{
	&#x2F;* dynamically allocate structures *&#x2F;
	struct device_x * devx = malloc(sizeof(*devx));
	memset(devx, 0, sizeof(*devx));

&#x2F;* set a parameter in the device_x structure so
	 * we can test for this in the callback
	 *&#x2F;
	devx-&amp;gt;device_x_specific_param_a = 1001;

&#x2F;* set up callback function *&#x2F;
	devx-&amp;gt;bd.device_callback = device_x_callback;

&#x2F;* we register the generic bus device structure
	 * as the bus layer does not need to know
	 * about the device_x stucture.  Note, the
	 * devx structure is not stored anywhere, yet
	 * its location is being preserved without
	 * specifically passing it to the bus
	 * layer.
	 *&#x2F;
	register_with_bus(&amp;amp;devx-&amp;gt;bd);
}

int main()
{

&#x2F;* test the above system *&#x2F;

&#x2F;* first, initialize device_x *&#x2F;
	device_x_init();

&#x2F;* now, start the bus.  This should make
	 * a callback into the device_x
	 *&#x2F;
	start_bus();
}

&#x2F;* when run, this program returns:
 * device_x_callback called!, device_x_specific_param_a = 1001
 *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Should you be using monotonic timers?</title>
        <published>2008-03-19T00:00:00+00:00</published>
        <updated>2008-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/201/should-you-be-using-monotonic-timers/"/>
        <id>https://bec-systems.com/201/should-you-be-using-monotonic-timers/</id>
        
        <content type="html" xml:base="https://bec-systems.com/201/should-you-be-using-monotonic-timers/">&lt;p&gt;In a &lt;a href=&quot;&#x2F;175&#x2F;how-to-implement-realtime-periodic-tasks-in-linux-applications&#x2F;&quot;&gt;previous article&lt;&#x2F;a&gt;, I covered some of the basics of Linux timers.  Any time you are doing any type of fixed time delay in a program, you should really be using monotonic times, so the delay will not be affected by system time changes.  In an effort to save cost, some embedded systems today do not have a battery backed up RTC, and instead get the time via GPS, NTP servers, or other clever means.  What this means is your applications had better be able to handle the system time changing as the system time may not be set until well after the unit boots.  This article describes how you can quickly test your system for timer problems.&lt;&#x2F;p&gt;
&lt;p&gt;There are two cases where delays may fail if you are using non-monotonic timers.  The first is if the time advances forward by a large amount.  Delays will expire immediately in this case.  The other case is if the time advances backward by a large amount.  Delays will never expire in this case.  To test for these situations, write a simple test application (sample included below) that rapidly changes the time and then test your application while the time is changing.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

int main()
{
  time_t system_time;
  static int count = 0;

printf(&amp;quot;Starting test application...\n&amp;quot;);
  while(1)
  {
    &#x2F;&#x2F; Sleep for 0.01 seconds
    usleep(10 * 1000);

system_time = time(NULL);
    system_time += 30;
    stime(&amp;amp;system_time);
    printf(&amp;quot;Cycle %d - system date&#x2F;time set to %s&amp;quot;, ++count, ctime(&amp;amp;system_time));
  }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 kernel update to 2.6.24</title>
        <published>2008-02-29T00:00:00+00:00</published>
        <updated>2008-02-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/199/compulab-cm-x270-kernel-update-to-2624/"/>
        <id>https://bec-systems.com/199/compulab-cm-x270-kernel-update-to-2624/</id>
        
        <content type="html" xml:base="https://bec-systems.com/199/compulab-cm-x270-kernel-update-to-2624/">&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;linux-2.6.24&#x2F;cm-x270&quot;&gt;kernel support&lt;&#x2F;a&gt; in OpenEmbedded for the Compulab cm-x270 has been updated to version 2.6.24.  The 2.6.24 kernel opens up several possibilities including better real time and &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;199&#x2F;compulab-cm-x270-kernel-update-to-2624&#x2F;content&#x2F;view&#x2F;78&#x2F;9&#x2F;&quot;&gt;high resolution timer&lt;&#x2F;a&gt; functionality, an improved SD Card driver, and a full SDIO stack with support for &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;199&#x2F;compulab-cm-x270-kernel-update-to-2624&#x2F;content&#x2F;view&#x2F;89&#x2F;9&#x2F;&quot;&gt;SDIO Wifi devices&lt;&#x2F;a&gt;.  Also included is a patch to set the default framebuffer depth to 16 for several commonly used displays.  Xfbev really does not like when you give it a 8-bit framebuffer when it is expecting 16, and typically returns a very unhelpful error message like: “error: Invalid argument”.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GESBC-9302E kernel update to 2.6.24, and reboot fix</title>
        <published>2008-02-18T00:00:00+00:00</published>
        <updated>2008-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/111/gesbc-9302e-kernel-update-to-2624-and-reboot-fix/"/>
        <id>https://bec-systems.com/111/gesbc-9302e-kernel-update-to-2624-and-reboot-fix/</id>
        
        <content type="html" xml:base="https://bec-systems.com/111/gesbc-9302e-kernel-update-to-2624-and-reboot-fix/">&lt;p&gt;I recently updated the GESBC-9302 machine support in OpenEmbedded to include the 2.6.24 released kernel.  Also, Glomation has kindly provided me with a patch for the software reboot problem which I have integrated into the OpenEmbedded build for the GESBC.   The patch files are part of the OpenEmbedded dev branch or can be obtained here:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux-2.6.24&#x2F;gesbc-9302&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux-2.6.24&#x2F;gesbc-9302&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Other related OpenEmbedded bits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux_2.6.24.bb&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux_2.6.24.bb&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;conf&#x2F;machine&#x2F;gesbc-9302.conf&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;conf&#x2F;machine&#x2F;gesbc-9302.conf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Future features to be integrated include RTC driver configuration, and support for loading Initramfs images from NOR flash.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Glomation GESBC-9302E Review</title>
        <published>2008-01-29T00:00:00+00:00</published>
        <updated>2008-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/107/glomation-gesbc-9302e-review/"/>
        <id>https://bec-systems.com/107/glomation-gesbc-9302e-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/107/glomation-gesbc-9302e-review/">&lt;p&gt;Recently, I’ve had the opportunity to work with a Glomation GESBC-9302E single board computer.  This SBC contains a Cirrus Logic EP9302 ARM processor and options for plenty of RAM and Flash memory which means you have many options for writing your applications including high level languages like C# and Python.  In this review, I’ll cover some of basic features of this board and where this board might be useful.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-the-gesbc-9302&quot;&gt;Why the GESBC-9302?&lt;&#x2F;h3&gt;
&lt;p&gt;One of the most attractive features of the GESBC-9302E is cost.  The base model with 32MB of RAM, and no NAND flash costs $95 at quantities of 1 unit.  For a model with 64MB of RAM, and 128MB of flash, the cost is $120.  Looking at the board, its simplicity is very evident.  There is basically a CPU, flash, ram, a few linear power supplies, and a very limited amount of support circuitry.  There really is not much to it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;gesbc_9302e_1-1.jpg&quot; alt=&quot;gesbc_9302e_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We are helping a customer use the GESBC-9302E in a project where it is functioning as a gateway between a local Zigbee wireless network, and a server located on the internet.  The customer had originally considered using a Linksys NSLU2 for the gateway device during the alpha testing, but upon consideration it seemed like the GESBC-9302E is a better choice in this application for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the GESBC does not cost a lot more than a NSLU2&lt;&#x2F;li&gt;
&lt;li&gt;you can buy the GESBC with plenty of NAND flash.&lt;&#x2F;li&gt;
&lt;li&gt;the GESBC provides two serial ports&lt;&#x2F;li&gt;
&lt;li&gt;the GESBC provides many signals on headers than can be used with cables or a daughter card.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Having raw NAND flash on the board is a significant advantage in my opinion.  I’ve run into considerable hassles with consumer grade flash devices in the past (SD, USB Flash, etc).  Although there are industrial grade flash devices, they tend to be more expensive.  My preference at this point for reliable storage in an embedded Linux system is JFFS2 on a 64-128MB raw NAND flash device.  With 128MB of NAND flash, there is &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;67&#x2F;9&#x2F;&quot;&gt;plenty of space&lt;&#x2F;a&gt; for a full featured Linux distribution.&lt;&#x2F;p&gt;
&lt;p&gt;With 2 USB ports, plenty of general pupose I&#x2F;O pins (GPIO), and lots of memory, there is not a lot you can’t do with the GESBC in your typical headless control or gateway type application.  Being able to interface to a number of USB peripherals, and support for high level languages makes this SBC+Linux ideal for implementing a device that may need to talk web services or other complex network protocols.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;software-support&quot;&gt;Software Support&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the GESBC functionality is fairly well supported in the mainstream Linux kernel.  Simply configure the kernel for the EDB9302 machine and most things will just work.  There are several pieces missing from the mainstream kernel for the GESBC that are useful: NAND flash support, and a change needed to make the Ethernet work.  For the NAND flash, I extracted a MTD driver from the Glomation kernel source code.  The Ethernet change is a small tweak to the platform files.  These changes are available for the 2.6.24 kernel in a public git repository at: http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;linux-2.6-gesbc-9302.git.&lt;&#x2F;p&gt;
&lt;p&gt;The GESBC uses Redboot for the bootloader.  No complaints with the bootloader so far – it does everything I need including loading images from a TFTP server.  The bootloader does not support writing images to NAND flash, so to load an OS image into NAND flash you typically have to boot a Linux OS from NOR flash, USB flash, or NFS root, and then use the userspace mtdutils to write an image into NAND flash.&lt;&#x2F;p&gt;
&lt;p&gt;Glomation provides a sample Linux image, but I prefer to use images generated by OpenEmbedded so that I have support for things &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;87&#x2F;9&#x2F;&quot;&gt;like C#&lt;&#x2F;a&gt; , Python, and thousands of other packages.  Support for the GESBC has been added to OpenEmbedded and I’m in the process of updating the kernel support to 2.6.24.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Overall I’m very pleased with this SBC.  Glomation has been very responsive to requests and has been a good company to work with. I still need to apply a fix for a known soft reboot issue with the 2.6 kernel and enable a driver for the RTC on the SBC.    Future articles will detail how to load Linux images built with OpenEmbedded on this device.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Marvell Embedded SDIO Wifi Success</title>
        <published>2008-01-09T00:00:00+00:00</published>
        <updated>2008-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/197/marvell-embedded-sdio-wifi-success/"/>
        <id>https://bec-systems.com/197/marvell-embedded-sdio-wifi-success/</id>
        
        <content type="html" xml:base="https://bec-systems.com/197/marvell-embedded-sdio-wifi-success/">&lt;p&gt;As detailed in the article I wrote back in September of 2007 (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;75&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;75&#x2F;9&#x2F;&lt;&#x2F;a&gt;), getting  embedded wifi modules functioning is not a simple task.  However, due to recent advances in the Linux kernel, it looks like a viable solution for low-mid volume products is emerging.  This article provides a few details on how to get a Zcomax (Zcom) XG-180MU module working with a PXA270 processor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-setup&quot;&gt;System Setup&lt;&#x2F;h3&gt;
&lt;p&gt;The setup used includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Zcomax XG-180MU SDIO Wifi module&lt;&#x2F;li&gt;
&lt;li&gt;Compulab cm-x270 + sb-x270 system (includes the PXA270 processor)&lt;&#x2F;li&gt;
&lt;li&gt;Linux kernel 2.6.24-rc5&lt;&#x2F;li&gt;
&lt;li&gt;OpenEmbedded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Support for the Marvell 8385 and 8686 based Wifi chipsets is now included in the mainstream Linux kernel 2.6.24 release candidate source code.  To use this driver, enable the CONFIG_LIBERTAS_SDIO option.  I also had to enable the CONFIG_WIRELESS_EXT option to prevent a compile error, but this is probably required anyway to build a functioning wireless system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;firmware&quot;&gt;Firmware&lt;&#x2F;h3&gt;
&lt;p&gt;The firmware for the Marvell SDIO wifi solutions is downloaded at runtime, so the next challenge is to find firmware files.  I am working on a project that has access to a driver from Marvell, so I was able to extract this firmware from their source code header files.  I’m sure there are other places where this firmware is available.   The firmware files must be placed in the following location:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ ls &#x2F;lib&#x2F;firmware&#x2F;sd*
&#x2F;lib&#x2F;firmware&#x2F;sd8385.bin         &#x2F;lib&#x2F;firmware&#x2F;sd8385_helper.bin
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The version of udev used in OpenEmbedded determines the location of the firmware files.  The Libertas Linux driver requests these firmware files, and a userspace component of udev provides these files to the kernel.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;success&quot;&gt;Success&lt;&#x2F;h3&gt;
&lt;p&gt;The following kernel modules are required:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ lsmod
Module                  Size  Used by
pxamci                  7008  0
libertas_sdio           8488  0
mmc_core               46868  2 pxamci,libertas_sdio
libertas               85288  1 libertas_sdio
ieee80211              29956  1 libertas
ieee80211_crypt         4768  1 ieee80211
root@cm-x270:~$
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the result:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ modprobe pxamci
root@cm-x270:~$ mmc0: new SDIO card at address 0001
libertas: eth1: Marvell WLAN 802.11 adapter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;ifconfig -a
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;eth1      Link encap:Ethernet  HWaddr 00:60:B3:34:77:66
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very nice!&lt;&#x2F;p&gt;
&lt;p&gt;So it looks like there is finally an embedded Wifi solution for products that sell less than 500,000 units per year.  I also briefly tried this on a AT91SAM9260 system, but it did not work.  So there is still some work to do on the Linux SDHC driver for the AT91SAM9260.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>C# on embedded ARM Linux systems is now practical</title>
        <published>2007-12-15T00:00:00+00:00</published>
        <updated>2007-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/191/c-on-embedded-arm-linux-systems-is-now-practical/"/>
        <id>https://bec-systems.com/191/c-on-embedded-arm-linux-systems-is-now-practical/</id>
        
        <content type="html" xml:base="https://bec-systems.com/191/c-on-embedded-arm-linux-systems-is-now-practical/">&lt;p&gt;&lt;strong&gt;Update&lt;&#x2F;strong&gt;: Michael Dominic K. has kindly provided feedback on this article and has some additional &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lists.ximian.com&#x2F;pipermail&#x2F;mono-list&#x2F;2007-December&#x2F;037362.html&quot;&gt;points&lt;&#x2F;a&gt; about Mono and embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Mono has included support for ARM systems for some time, but with the release of Mono 1.2.6, and its inclusion in OpenEmbedded, it is now practical and easy to build and run C# applications on your everyday ARM Linux system.  Several ARM issues in 1.2.5 have been fixed, and thus far it seems the average program runs quite well.  In this article, we’ll explore what advantages C# offers over more traditional languages such as C or Python, and how OpenEmbedded simplifies adding C# support to your embedded system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-c&quot;&gt;Why C#&lt;&#x2F;h3&gt;
&lt;p&gt;Why is C# an attractive language for embedded Linux systems?  There are many reasons including memory protection and exception handling, native types, good threading support, extensive library, and developer productivity.  In the past, I’ve typically used C or Python for implementing large applications on embedded Linux systems.  This section will compare C# to my experiences with both languages.&lt;&#x2F;p&gt;
&lt;p&gt;A typical experience when implementing a large application in an embedded system is to deploy the system for field testing (before it is ready) and start getting reports that the application is crashing.  Somewhere in the mass of C code your team just wrote there is a stray pointer clobbering something it should not.  Of course this does not happen in the lab where you have access to the machine, but in some piece of industrial equipment many miles away.  And, you cannot reproduce the problem in the lab because with embedded systems, simulating a real world situation is challenging because it is difficult to simulate real I&#x2F;O.  This is less of a problem with desktop applications where you are less dependent on external I&#x2F;O.  Sound familiar?  Even if you can reproduce the problem on a machine you have access to (perhaps even &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;58&#x2F;9&#x2F;&quot;&gt;remotely&lt;&#x2F;a&gt;), the problem can be caused by a stray pointer corrupting data in a completely unrelated piece of code.  So while the debugger may tell you what got clobbered, you still don’t know exactly who did it.  If you have lots of time and a team to do lots of testing, this is less of an issue, but available resources and time to market sometimes don’t give you all you need to do the job right before it gets to the field.  One solution to this problem is use a language that has exception handling (I’ve used Python a lot &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;46&#x2F;9&#x2F;&quot;&gt;in the past&lt;&#x2F;a&gt;), and log all exceptions.  If something bad happens in the field, I ask for the log.  With the stack trace in the log, and some focused testing I can usually find the problem relatively quickly.  Add in the memory protection and things get a lot easier.  For small applications this is not so much of an issue, but lets face it, now that we &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;70&#x2F;9&#x2F;&quot;&gt;have access to very capable hardware at a low cost&lt;&#x2F;a&gt;, applications in embedded systems tend to get large and complex.  C# gives you exception handling and memory protection that makes problems much easier to find and debug; especially during field testing.&lt;&#x2F;p&gt;
&lt;p&gt;While its hard to beat Python or Ruby for developer productively and ease of use, there are performance issues like threading support, and support for static types that must be weighed in the balance.  With Python, everything is an object or a reference.  The checking is done at run time to make sure a variable is of the correct type.  With C#, this is done at compile time (much like C).  While it is generally more work to write code in C# than Python, the compiler tends to catch more errors for you.  There is probably also a performance advantage to being able to implement simple variables statically.  Threading support is another consideration and is often critical in embedded systems because you are usually tending to I&#x2F;O, processing data, running a user interface, etc.  This type of problem is well suited to a threaded application.  Threading in Python is implemented using a global interpreter lock mechanism that is inefficient in some situations.  C# threading support is more similar to C.  While it may require you to do more manual locking than Python, it gives you more control.&lt;&#x2F;p&gt;
&lt;p&gt;When it comes to developer productivity, in my experience C# is more work to write than Python or Ruby, but less work than C.  So it seems to fall somewhere in the middle of the spectrum.&lt;&#x2F;p&gt;
&lt;p&gt;So, C# seems to fall nicely into the middle ground between C and very high level languages such as Python and Ruby.  It offers many of the advantages at both ends of the spectrum and seems to be a nice balance for programming embedded systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mono&quot;&gt;Mono&lt;&#x2F;h3&gt;
&lt;p&gt;What is Mono?  From the Mono &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Main_Page&quot;&gt;web site&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Mono provides the necessary software to develop and run .NET client and server applications on Linux, Solaris, Mac OS X, Windows, and Unix.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mono includes all the necessary components to build and run C# applications on Linux systems including embedded ARM Linux systems.   The Mono source tree is fairly clean and is nicely segmented between native and managed code.  This is critical when it comes to cross compiling.  The Mono team has also stuck with traditional build tools such as autotools which makes the project a lot easier to cross compile for an embedded target.&lt;&#x2F;p&gt;
&lt;p&gt;Mono includes a very extensive C# library that is comparable to Microsoft’s implementation.  Most of what you might ever need is built right into the Mono class library; much like Python or Java.  With C or C++, you typically need to add a number of additional libraries to the system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mono-support-in-openembedded&quot;&gt;Mono Support in OpenEmbedded&lt;&#x2F;h3&gt;
&lt;p&gt;OpenEmbedded includes comprehensive support for Mono including crosscompiling support, granular packaging of the Mono class library, and automatic run-time dependency generation for Mono applications.  In this section, we’ll see how OpenEmbedded can make your life a lot easier.&lt;&#x2F;p&gt;
&lt;p&gt;Mono is typically cross compiled in two &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Mono:ARM&quot;&gt;steps&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The managed portions are generated by compiling Mono for the host machine architecture.  A very nice feature of the Mono build process is that it can bootstrap itself.&lt;&#x2F;li&gt;
&lt;li&gt;The native only portion of Mono is then cross compiled over top of the above output and the native host binaries will then get replaced with the cross compiled target binaries.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To implement this, there are two recipes implemented in OpenEmbedded.  The &lt;em&gt;mono-mcs-intermediate&lt;&#x2F;em&gt; is used to generate all the managed binaries, while the &lt;em&gt;mono&lt;&#x2F;em&gt; recipe builds only the native portion of Mono.  The first step when building the &lt;em&gt;mono&lt;&#x2F;em&gt; cross recipe is to extract the results of the &lt;em&gt;mono-mcs-intermediate&lt;&#x2F;em&gt; in the install directory and then proceed to overlay the native binaries produced by the &lt;em&gt;mono&lt;&#x2F;em&gt; recipe in that same directory.  As mentioned before, the use of standard tools like autotools makes all this work pretty well.  All of this is automated in OpenEmbedded and happens when you run “bitbake mono”.&lt;&#x2F;p&gt;
&lt;p&gt;One issue with embedded systems is you typically have limited flash&#x2F;disk space.  So you only want to include that pieces of Mono in your target image that your application needs.  The OE build of Mono makes this very easy by packaging up the Mono class library into a number of different packages.  The dependencies between packages is automatically tracked so that if you add a Mono package to an OE build, its dependencies will automatically be included with no extra work on your part.  This mechanism uses the &lt;em&gt;monodis&lt;&#x2F;em&gt; tool to figure out what each Mono library provides and the dependencies of each library.  This saves a huge amount of very tedious manual work to have all this automated.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;building-and-running-your-mono-application&quot;&gt;Building and Running your Mono application&lt;&#x2F;h3&gt;
&lt;p&gt;Now that we have Mono running on our target system, there are a number of ways to build Mono applications to run on the target.  The quick-n-dirty method is to simply build the mono binary on any system, copy it to your embedded system and run it.  Building and running your applications is easy as Mono binaries are platform independent and will run on any system that supports Mono.  So, you don’t need to worry about cross compiling, toolchains, etc.&lt;&#x2F;p&gt;
&lt;p&gt;The quick-n-dirty method works well for getting started, experimenting, etc, but there are several advantages to integrating your Mono application into an OpenEmbedded build, even though you technically don’t need to worry about cross compiling.  The first reason is packaging.  A very simple OpenEmbedded recipe provides an easy way to automatically fetch your project from a separate version control system, build it, and package it properly into the OS image for your target.  It also gives you the ability to deploy updates to target systems using the ipkg package manager.   The second reason is automatic run-time dependencies.  If you inherit the &lt;em&gt;mono&lt;&#x2F;em&gt; OpenEmbedded class, all of the Mono components your application needs are automatically added to the image.  An example OpenEmbedded recipe for a Mono application is shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DESCRIPTION = &amp;quot;My Application&amp;quot;

DEPENDS = &amp;quot;mono&amp;quot;

SRCREV = &amp;quot;${AUTOREV}&amp;quot;
PV = &amp;quot;1.0+svnr${SRCREV}&amp;quot;
PR = &amp;quot;r1&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;svn.mycompany.com&#x2F;svn&#x2F;myproject&#x2F;;module=myapplication;proto=https&amp;quot;

S = ${WORKDIR}&#x2F;myapplication
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;inherit autotools mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above recipe assume you have set up your application to be built with autotools, which is a good idea.  This &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Guidelines:Application_Deployment&quot;&gt;page&lt;&#x2F;a&gt; provides lots of good information on building Mono applications using autotools.  You can also look at a number of open source applications such as &lt;em&gt;Tomboy&lt;&#x2F;em&gt; for additional clues about how to use autotools with Mono.  For a simple application that I built, the following run time dependencies where automatically determined by OpenEmbedded: *mono, libmono0, libmono2.0-cil, libmono-corlib2.0-cil.*Each of these dependencies may have additional dependencies, and in this case a dozen or so mono packages ended up being installed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;As embedded systems become larger and more capable, we can expect that higher level languages such as C# and Java will start to become more common.  In the past, the focus on embedded systems programming was often efficiency, minimizing resource utilization, etc.  Now that &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;70&#x2F;9&#x2F;&quot;&gt;very capable hardware is becoming cheaper&lt;&#x2F;a&gt;, the focus in some systems is shifting to features and time to market.  Operating systems like Linux and languages like C# help us reach those goals and develop competitive products     quickly with small teams.  C# provides the features needed to rapidly develop, deploy, and debug complex applications that still perform reasonably well.  OpenEmbedded provides a way to manage builds, so that you can focus on real work instead of tedious build issues.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mono 1.2.6 added to OpenEmbedded</title>
        <published>2007-12-14T00:00:00+00:00</published>
        <updated>2007-12-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/194/mono-126-added-to-openembedded/"/>
        <id>https://bec-systems.com/194/mono-126-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/194/mono-126-added-to-openembedded/">&lt;p&gt;I recently updated the Mono recipes in OpenEmbedded to include the Mono 1.2.6 version.  Several critical bugs that were present in 1.2.5 have been fixed, and its looking very good.  More on this later …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded Linux development on Windows???</title>
        <published>2007-11-30T00:00:00+00:00</published>
        <updated>2007-11-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/189/embedded-linux-development-on-windows/"/>
        <id>https://bec-systems.com/189/embedded-linux-development-on-windows/</id>
        
        <content type="html" xml:base="https://bec-systems.com/189/embedded-linux-development-on-windows/">&lt;p&gt;From &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.embedded.com&#x2F;design&#x2F;opensource&#x2F;204300381&quot;&gt;http:&#x2F;&#x2F;www.embedded.com&#x2F;design&#x2F;opensource&#x2F;204300381&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Host platform&lt;&#x2F;strong&gt;
Although everything I will describe can be also done on a Windows host, I recommend using Linux. It’s more convenient, and more tools and utilities are available. And if you rely on a few Windows applications such as Word and Outlook, you can still run them on Linux in emulation using VirtualBox, Wine, or other commercial package. If you’re new to Linux, using a Linux host will also force you to learn the new platform faster.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;How true.  Those who think they can do embedded Linux development without learning the basics of using a Linux desktop computer are in for a long hard road, and they are missing out on a valuable opportunity to learn a lot about embedded Linux development.  This is the primary advantage of embedded Linux – there are many things in common with desktop and server systems.  There is a tremendous amount of reuse.  Things can be easily prototyped on your desktop Linux system before deploying to an embedded system.  Instead of viewing the suggested that a Linux workstation be used for embedded Linux development as stumbling block, it should be viewed as a huge advantage.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab EM-X270 Review</title>
        <published>2007-11-07T00:00:00+00:00</published>
        <updated>2007-11-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/94/compulab-em-x270-review/"/>
        <id>https://bec-systems.com/94/compulab-em-x270-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/94/compulab-em-x270-review/">&lt;p&gt;The EM-X270 is a full featured computer board from Compulab (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.compulab.co.il&#x2F;x270em&#x2F;html&#x2F;x270-em-datasheet.htm&quot;&gt;http:&#x2F;&#x2F;www.compulab.co.il&#x2F;x270em&#x2F;html&#x2F;x270-em-datasheet.htm&lt;&#x2F;a&gt;) designed for handheld&#x2F;mobile applications.  The board includes options for about anything you might need in a portable system including a PXA270 processor, GSM radio, GPS, Wifi, Bluetooth, Audio, SD&#x2F;MMC, USB, battery circuitry, and the list goes on.  The EM-X270 is designed to give you a big head start in designing a handheld computing device, and can significantly reduce time to market and design costs.  This article provides a high level overview of this product, how it might be used, and lots of photos.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;em-x270-overview&quot;&gt;EM-X270 Overview&lt;&#x2F;h3&gt;
&lt;p&gt;The EM-X270 is a computer board about the size of a display you might find in a typical PDA.  While the size is probably a little large to be used in consumer devices like phones and PDAs, it seems like a nice size for slightly larger products used in vertical industries.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_1-1.jpg&quot; alt=&quot;em-x270_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As already mentioned, the EM-X270 includes about all the base features you might need in a mobile computing device.  An expansion connector is also included that allows you to easily add custom circuitry to the system.  The stack-up between the EM-X270 and an expansion board is shown below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_2-1.jpg&quot; alt=&quot;em-x270_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The EM-X270 differers from most other embedded computer modules in that it is a little more application specified, and quite a bit more circuitry is included in the design such as power supplies, battery charging circuitry, radios, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-em-x270&quot;&gt;Why EM-X270?&lt;&#x2F;h3&gt;
&lt;p&gt;Why are we interested in the EM-X270?  If all you need is a generic handheld computer, there are plenty of options from PDAs to off-the-shelf industrial handhelds.  However, if you need a handheld that provides some additional features not typically found in existing devices, then you can use the EM-X270 plus a custom baseboard and packaging to add your high value features.  Depending what you need to add, the expansion board can be a simple 4 layer board which is very easy to design and manufacture.  All of the complex PCB design and assembly is already done for you on the EM-X270 module.  This allows low to moderate volume manufactures design products where they would not otherwise have the time and budget for designing a full custom processor board.   Some example applications might be handheld products for the medical, industrial, and test and measurement industry.&lt;&#x2F;p&gt;
&lt;p&gt;Compulab’s pricing model is also very interesting.  Compulab will custom build EM-X270 modules with just the options you need.  The base price without any extra features (such as radios) is $122 for 1000 pieces.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-eb-x270-evaluation-kit&quot;&gt;The EB-X270 Evaluation Kit&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides a EB-X270 Evaluation kit for getting started with EM-X270 development.  Like their other Evaluation klits, is is very full featured and very well done.   An extender board is provided that adds Ethernet, JTAG, and several other useful connectors for development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_3-1.jpg&quot; alt=&quot;em-x270_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The eval kit also includes all necessary cables, a display, battery, etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_4-1.jpg&quot; alt=&quot;em-x270_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;software-for-the-em-x270&quot;&gt;Software for the EM-X270&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides software support for both Windows CE and Linux.  This includes very up-to-date support for kernel version 2.6.23.  EM-X270 machine support has also been included in the OpenEmbedded project for building full featured Linux images.  This combination will drastically reduce development costs compared to solutions provided by many other vendors.  All too often, single board computer vendors provide an ancient kernel, a hacked up root file system and call it a “Linux BSP”.  Actually, any time the term “Linux BSP” is used, you should probably be a bit wary.  A much more attractive solution for those of us building products using Linux is for processor and module vendors to say “our products are supported in the mainstream kernel and OpenEmbedded sources”.  Compulab is doing it right.&lt;&#x2F;p&gt;
&lt;p&gt;OpenEmbedded provides many interesting options for devices like the EM-X270.  One of the most interesting might be the ability to run the OpenMoko software on industrial devices.&lt;&#x2F;p&gt;
&lt;p&gt;Compulab provides a Linux demo image built with OpenEmbedded that runs the GPE Palmtop Environment.  The method for loading this image is interesting, and similar to the method I have been using for some time with systems based on the cm-x270 module (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;82&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;82&#x2F;9&#x2F;&lt;&#x2F;a&gt;) in that it used mtd-utils from a running Linux system to erase and write to the NAND flash.  The bootloader in the EM-X270 is able to boot a kernel and rootfs directly from a USB Flash disk.  This “LiveDisk” image, as Compulab calls it, contains a small utility that programs an image from the USB flash disk directly into NAND flash.&lt;&#x2F;p&gt;
&lt;p&gt;As with any modern Linux based embedded system, there is a lot going on in a very small package.  Managing this complexity effectively requires some amount of experience.  Stay tuned for future articles that discuss using OpenEmbedded to build software for the EM-X270.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;additional-photos&quot;&gt;Additional Photos&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_5-1.jpg&quot; alt=&quot;em-x270_5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_6-1.jpg&quot; alt=&quot;em-x270_6&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_7-1.jpg&quot; alt=&quot;em-x270_7&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux 2.6.23 for the Compulab cm-x270</title>
        <published>2007-10-22T00:00:00+00:00</published>
        <updated>2007-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/187/linux-2623-for-the-compulab-cm-x270/"/>
        <id>https://bec-systems.com/187/linux-2623-for-the-compulab-cm-x270/</id>
        
        <content type="html" xml:base="https://bec-systems.com/187/linux-2623-for-the-compulab-cm-x270/">&lt;p&gt;Updated 2.6.23 kernel patches for the Compulab cm-x270 are now available in OpenEmbedded:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;linux-2.6.23&#x2F;cm-x270&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;linux-2.6.23&#x2F;cm-x270&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The cm-x270 support in OpenEmbedded has undergone a lot of clean-up in recent weeks.  Now is a good time to give OpenEmbedded a try if you need a full featured Linux distribution for the cm-x270.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 NAND flash eraseblock sizes</title>
        <published>2007-10-08T00:00:00+00:00</published>
        <updated>2007-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/181/compulab-cm-x270-nand-flash-eraseblock-sizes/"/>
        <id>https://bec-systems.com/181/compulab-cm-x270-nand-flash-eraseblock-sizes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/181/compulab-cm-x270-nand-flash-eraseblock-sizes/">&lt;p&gt;If you are having trouble mounting a JFFS2 file system on a Compulab cm-x270 module, you may have a device that has a NAND flash with 16KiB eraseblocks.  All of the devices I have personally used to date have had 128KiB eraseblocks, but I just helped a cm-x270 user through some flash issues and after much pain discovered the eraseblock size was 16KiB on his module.  A variable has been added to the cm-x270.conf file in OE to set the eraseblock size that can be overridden in your local.conf file if you are using OpenEmbedded to generate jffs2 images:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.openembedded.net&#x2F;?p=openembedded.git;a=blob;f=conf&#x2F;machine&#x2F;cm-x270.conf;h=3c21c546b1320914c9b5d2c44e7332782fc58748&quot;&gt;http:&#x2F;&#x2F;git.openembedded.net&#x2F;?p=openembedded.git;a=blob;f=conf&#x2F;machine&#x2F;cm-x270.conf;h=3c21c546b1320914c9b5d2c44e7332782fc58748&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Howto load Openembedded on the Compulab cm-x270 computer module</title>
        <published>2007-10-08T00:00:00+00:00</published>
        <updated>2007-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/183/howto-load-openembedded-on-the-compulab-cm-x270-computer-module/"/>
        <id>https://bec-systems.com/183/howto-load-openembedded-on-the-compulab-cm-x270-computer-module/</id>
        
        <content type="html" xml:base="https://bec-systems.com/183/howto-load-openembedded-on-the-compulab-cm-x270-computer-module/">&lt;p&gt;There are quite a few people using (or would like to use) OpenEmbedded on the Compulab cm-x270.  The cm-x270 is a high performance, low cost computer module that can be used with a custom baseboard in embedded systems (see &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&lt;&#x2F;a&gt; for a review).  I get a lot of questions on how to load OpenEmbedded on this system, so this howto attempts to detail a procedure that can be used to load OpenEmbedded.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-nand-flash-wrinkle&quot;&gt;The NAND Flash wrinkle&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux solution provided by compulab includes a proprietary NAND flash driver.  Most developers are interested in using standard Linux MTD drivers with the JFFS2 filesystem, but its not readily obvious how to flash a JFFS2 NAND image using the cm-x270 bootloader.  Fortunately, you can boot a small Linux image stored in NOR flash, and then use standard MTD utilities to then flash the NAND jffs2 image.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-the-needed-images&quot;&gt;Creating the needed images&lt;&#x2F;h3&gt;
&lt;p&gt;For this method, you need to generate two images: a small image to run from NOR flash, and a larger full featured image that will run from NAND flash.  Because you only have about 2.3MB of NOR flash, you want to use uclibc in the NOR image as it is much smaller.  A base Linux image that will boot into a shell using uclibc and contains a few utilities is about 1MB in size, which leaves plenty of space for custom apps should you need them in this partition.  The local.conf settings to build this image are:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;MACHINE = &amp;quot;cm-x270&amp;quot;
DISTRO = &amp;quot;angstrom-2008.1&amp;quot;
ANGSTROM_MODE = &amp;quot;uclibc&amp;quot;
IMAGE_FSTYPES = &amp;quot;jffs2 tar cpio.gz&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, “bitbake angstrom-minimal-image-with-mtd-utils”, and OE will generate a “minimalist-image-mtdutils-cm-x270.cpio.gz” image that can be programmed into the NOR ramdisk partition using the cm-x270 bootloader, and tftp download.  A kernel will also be built that should be programmed into the kernel partition.&lt;&#x2F;p&gt;
&lt;p&gt;To build the NAND image, simply remove the ANGSTROM_MODE line, and “bitbake angstrom-console-image”.  This will generate a “console-image-cm-x270.rootfs-summary.jffs2” that can be programmed into NAND flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;programming-images&quot;&gt;Programming Images&lt;&#x2F;h3&gt;
&lt;p&gt;Loading the software onto the cm-x270 is a multi-step process.  The first step is to the load the kernel image and the minimalist-image into NOR flash using the cm-x270 bootloader and tftp.  After this is accomplished, run the following commands to boot into the NOR flash rootfs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ramdisk on&lt;&#x2F;li&gt;
&lt;li&gt;bootos&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If successful, you will be presented with a prompt – log in as user root, and no password.&lt;&#x2F;p&gt;
&lt;p&gt;You now need to download the jffs2 NAND image into RAM on the cm-x270.  One way to do this is to use the tftp download feature in busybox:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;tftp -g -r console-image-cm-x270.rootfs-summary.jffs2 &amp;lt;tftp server IP&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point you can program the jffs2 image into NAND flash:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;flash_eraseall -j &#x2F;dev&#x2F;mtd3&lt;&#x2F;li&gt;
&lt;li&gt;nandwrite &#x2F;dev&#x2F;mtd3 console-image-cm-x270.rootfs-summary.jffs2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After programming completes, reboot the system and enter the following in the cm-x270 bootloader:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ramdisk off (this will disable the initramfs in NOR flash)&lt;&#x2F;li&gt;
&lt;li&gt;bootos&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At this point, your system should boot into the main NAND rootfs.  With a little imagination, it should be obvious that you can do a lot of neat things with this type of setup by extending the functionality in the NOR rootfs including field upgrades and system recovery.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mono support in OpenEmbedded and Openmoko packages</title>
        <published>2007-10-04T00:00:00+00:00</published>
        <updated>2007-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/179/mono-support-in-openembedded-and-openmoko-packages/"/>
        <id>https://bec-systems.com/179/mono-support-in-openembedded-and-openmoko-packages/</id>
        
        <content type="html" xml:base="https://bec-systems.com/179/mono-support-in-openembedded-and-openmoko-packages/">&lt;p&gt;&lt;em&gt;Original article published&lt;&#x2F;em&gt;2007-10-04&lt;&#x2F;p&gt;
&lt;p&gt;As of today, the Mono build in OpenEmbedded is working pretty well.  Mono support for ARM and other embedded architectures should add some interesting capabilities for embedded Linux devices.  Having written a number of large embedded Linux applications, I can really appreciate the advantages of high level languages for exception handling.  It is also interesting to note that Java support in OpenEmbedded is making progress as well (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;jalimo.org&#x2F;wiki&#x2F;doku.php&quot;&gt;http:&#x2F;&#x2F;jalimo.org&#x2F;wiki&#x2F;doku.php&lt;&#x2F;a&gt;).  Windows CE developers have already taken to the .net compact framework in a big way, so its nice to see similar capabilities for embedded Linux systems.&lt;&#x2F;p&gt;
&lt;p&gt;A feed has been set up for installing mono packages on your Openmoko phone.  Add the following line to a &#x2F;etc&#x2F;ipkg&#x2F;*-feed.conf file:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;src&#x2F;gz mono-armv4t http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;feed&#x2F;openmoko&#x2F;mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ipkg update
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;ipkg install mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The packaging is fairly granular, so look at the listing in the above URL to see a complete list of what is available.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to implement realtime periodic tasks in Linux applications</title>
        <published>2007-09-25T00:00:00+00:00</published>
        <updated>2007-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/175/how-to-implement-realtime-periodic-tasks-in-linux-applications/"/>
        <id>https://bec-systems.com/175/how-to-implement-realtime-periodic-tasks-in-linux-applications/</id>
        
        <content type="html" xml:base="https://bec-systems.com/175/how-to-implement-realtime-periodic-tasks-in-linux-applications/">&lt;p&gt;(see also &lt;a href=&quot;&#x2F;201&#x2F;should-you-be-using-monotonic-timers&#x2F;&quot;&gt;should you be using monotonic timers?&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Have you ever wondered what is the best way to implement periodic tasks in Linux applications – something better than usleep()?  This article covers a number of issues related to this subject including real-time tasks, the different timers available, timer resolution, and how to implement periodic tasks accurately so that error is not accumulated.  The recent inclusion of the high-resolution timers in the mainstream kernel makes this a very interesting subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;high-resolution-timers&quot;&gt;High Resolution Timers&lt;&#x2F;h3&gt;
&lt;p&gt;Historically Linux has done all timing off the OS timer tick which is usually between 1ms and 10ms.  While this is adequate for many tasks, it is really nice to have a high resolution timer for timing tasks.  With the integration of the high resolution timers into the mainstream Linux source tree, this is now possible.  From a user space perspective, there are no API changes.  The only difference you will notice is that now you can sleep for less than OS timer tick period.  clock_getres() can be used to check the timer resolution and will tell you instantly if you have high resolution timer support.  If the clock resolution is 1ns, you have high res timer support.  Realistically, you can’t delay for 1ns in a Linux application, but delays in the range of 100us should be possible, and depending on the configuration, much better performance is possible.  The kernel config entry for high resolution timers is CONFIG_HIGH_RES_TIMERS.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-difference-between-clock-realtime-and-clock-monotonic&quot;&gt;The difference between CLOCK_REALTIME and CLOCK_MONOTONIC&lt;&#x2F;h3&gt;
&lt;p&gt;Some of the Linux timer functions take a &lt;em&gt;clockid_t&lt;&#x2F;em&gt; argument that can be specified as CLOCK_REALTIME, or CLOCK_MONOTONIC.  The big difference between these two is that changing the system time will have an affect on CLOCK_REALTIME, thus affecting your timers.  Changing the system time will have no affect on CLOCK_MONOTONIC – it will always count upward.  For periodic tasks, CLOCK_MONOTONIC may be more applicable.  The best way to get burned using CLOCK_REALTIME is when your application takes a timestamp, does something, takes another time stamp and then compares them.  If you are using CLOCK_REALTIME, and the system time gets changed between the two timestamps, your comparison will not be valid.  For most timeouts and relative timekeeping in Linux, use CLOCK_MONOTONIC.  This issue becomes more important as many systems now have a process that periodically sets the time automatically from network time servers, and you have no idea when this might happen.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preemption&quot;&gt;Preemption&lt;&#x2F;h3&gt;
&lt;p&gt;Kernel preemption (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;69&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;69&#x2F;9&#x2F;&lt;&#x2F;a&gt; ) makes a huge difference in the performance of real time applications by allowing the kernel to be preempted by higher priority application processes.  Historically, any kernel code that was runnable ran before the kernel returned control to applications.  This all changes with kernel preemption.  Kernel preemption has been available in mainline kernels for some time now (I think since 2.6.16).  The worst offender I’ve found for locking the kernel for long periods of time have been flash drivers – especially proprietary ones.  But, even jffs2 can cause problems in realtime applications without kernel preemption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-preempt-rt-patch&quot;&gt;The PREEMPT_RT patch&lt;&#x2F;h3&gt;
&lt;p&gt;Much of the realtime work being done for Linux is maintained in the PREEMPT_RT patch.  Bits of this patch have already been merged into the mainline kernel, but there is still a lot of very useful functionality in the patch and it should be considered if you are doing any type of realtime work.  More details will be presented in a future article.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;absolute-vs-relative-timekeeping&quot;&gt;Absolute vs Relative timekeeping&lt;&#x2F;h3&gt;
&lt;p&gt;When implementing a periodic task, you really want to base your timekeeping off an absolute time, versus relative delays such as usleep().  It is not possible to achieve precise periodic activation with a relative sleep such as usleep().  The reason for this is you must first get the current time, make a calculation to determine how long to sleep, and then call the relative sleep function.  If your process gets preempted between the time you acquire the timestamp, and the sleep, your relative sleep time will probably be wrong.  This problem is solved by using the clock_nanosleep() function.  clock_nanosleep() can be called with the TIMER_ABSTIME value in the flags argument.  If  the TIMER_ABSTIME flag is set, then clock_nanosleep() will sleep until the absolute timer value is reached.  It does not matter if you get preempted between the time you take a timestamp, and the sleep function.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;In summary, if you want to implement accurate, realtime, periodic tasks in a Linux application, consider the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use high resolution timers.  Although Linux is still limited in its response time, at least the scheduling resolution is now quite high.&lt;&#x2F;li&gt;
&lt;li&gt;Enable kernel preemption.  This makes sure long kernel processes don’t get in the way of your real-time application process.&lt;&#x2F;li&gt;
&lt;li&gt;Use the CLOCK_MONOTONIC for relative timekeeping.  You don’t want your application to lock up due to the system time changing.&lt;&#x2F;li&gt;
&lt;li&gt;use the clock_nanosleep() function instead of relative delays like usleep().  This is the only way to accurately schedule periodic tasks.&lt;&#x2F;li&gt;
&lt;li&gt;if needed, apply the PREEMPT_RT patch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The clock_nanosleep man page also includes a lot of useful information about timer functions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Embedded WiFi module Quest</title>
        <published>2007-09-19T00:00:00+00:00</published>
        <updated>2007-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/90/the-embedded-wifi-module-quest/"/>
        <id>https://bec-systems.com/90/the-embedded-wifi-module-quest/</id>
        
        <content type="html" xml:base="https://bec-systems.com/90/the-embedded-wifi-module-quest/">&lt;p&gt;&lt;em&gt;original article written in Sept, 2007&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;How does one implement WiFi functionality in vertical, low volume portable products?  This is a good question, and one I’ve been struggling with for the past 3 months.  I have a customer who is designing a portable data acquisition system based on a AT91SAM9260 processor, and needs WiFi functionality.  The fundamental problem is that no one has time to deal with low volume customers, and the task of implementing WiFi functionality is obviously complex.  At volumes of 5000 units a year or less, it makes a lot of sense to go with a WiFi module rather than trying to integrate the WiFi chipset on the board.  This article covers some of the options we have looked at and some of the possible solutions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-is-wifi-done-on-x86-systems&quot;&gt;How is WiFi done on x86 systems?&lt;&#x2F;h3&gt;
&lt;p&gt;With desktop Windows, most devices are well supported by device manufacturers.  With x86 Linux some of the devices are well supported by OSS drivers, but these tend to be PCI or USB devices.  Some of the devices that are not supported can still be used by running the Windows NDIS drivers inside of ndiswrapper, which allows you to run the Windows driver on a x86 Linux system, but this obviously does not work very well on non-x86 processors such as ARM.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wifi-solutions-for-portable-embedded-systems&quot;&gt;WiFi solutions for portable, embedded systems&lt;&#x2F;h3&gt;
&lt;p&gt;While there are many off-the-shelf solutions for PCs, Notebooks, etc, the current solutions are generally in the USB formfactor.  The ideal solution for portable systems running non-x86 processors are the small modules that connect to the host processor using the SDIO or SPI bus – like the modules you would find in newer cell phones and PDAs.  Older modules tend to use the Compact Flash interface, but these modules tend to be larger and are not packaged as nicely for deeply embedded applications.  So Ideally we want:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a modules with a SDIO or SPI interface&lt;&#x2F;li&gt;
&lt;li&gt;packaging options such as solder down for robust packaging&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The scope of this article is limited to modules that implement a SPI or SDIO interface.  Why are we interested in modules?  Putting a WiFi chip down on a custom PCB is a lot of work.  Because the WiFi silicon includes a processor, if things do not work, it may be very difficult to debug.  There is also the issue of factory calibration which usually requires proprietary PC based tools that can communicate directly with the WiFi silicon.  If the WiFi silicon is buried in your product, getting all this to work can be a challenge.  The test equipment required for calibration is expensive.  Add to this the difficulty in getting support from anyone who makes WiFi silicon …&lt;&#x2F;p&gt;
&lt;h3 id=&quot;complexity&quot;&gt;Complexity&lt;&#x2F;h3&gt;
&lt;p&gt;It should be noted that WiFi modules are fairly complex devices.  They are typically based on a highly integrated IC that includes an ARM processor, Flash memory, and radio circuitry.  The fact that these modules include a significant amount of firmware on the module contributes significantly to the complexity of getting WiFi solutions to work properly.  Hopefully no bugs are encountered in the module firmware, because I can only imagine how difficult it would be to get these fixed for a small customer.   The fact that the module firmware is involved in many of the WiFi functions like authentication further complicates the problem with the abundance of authentication and encryption options available for WiFi.   The worst possible problem is the case where you must design an embedded WiFi system that must operate at the enterprise level in every environment.  It is one thing to design a system that works most of the time in most environments where WiFi is more of a convenience (like a Cell phone or PDA).  It is another thing to design an industrial grade system where it must work all the time and in all environments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-fundamental-problems-with-low-volume-embedded-wifi&quot;&gt;The Fundamental Problems with low volume embedded WiFi&lt;&#x2F;h3&gt;
&lt;p&gt;I have never worked with a technology with so many dead ends as embedded WiFi modules.  Many of the companies I email or call never even bother to return emails and phone calls.  This is certainly true of the chipset manufactures.  From what I can gather, the fundamental problems are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;WiFi implementation is difficult; therefore, a manufacturer’s scarce resources are dedicated to high volume customers.  Low volume customers are a significant distraction.&lt;&#x2F;li&gt;
&lt;li&gt;WiFi companies are very busy right now – they are not hungry for business from small customers.&lt;&#x2F;li&gt;
&lt;li&gt;WiFi solutions are very competitive and highly proprietary.  Many companies are very secretive and will not release driver source code.  This is certainly true at the module firmware level.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are many WiFi module manufacturers and resellers out there, but very few of them offer any type of driver solution for Windows CE or Linux other than binary modules that are supposed to work on perhaps one reference platform.  Sorry, this is not going to cut it.  So, with plenty of hardware available, the gating item is the availability of software drivers and knowledge of how to use the software.  It would seem to me that this is the perfect opportunity for chipset vendors to open source some drivers and develop vibrant support communities so that their modules can be used without a lot of hand-holding by the chipset vendors.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;so-what-are-the-options&quot;&gt;So What are the options?&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;atheros-ar6001&quot;&gt;Atheros AR6001&lt;&#x2F;h4&gt;
&lt;p&gt;The Atheros AR6001 seems like a nice solution.  The driver situation for the AR6001 is progressing.  For Windows CE, there is an opensource WinCE 6.0 driver available at:  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.codeplex.com&#x2F;CEWifiDriverAR6000&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.codeplex.com&#x2F;CEWifiDriverAR6000&#x2F;&lt;&#x2F;a&gt;.  Unfortunately, this project appears to be a snapshot of code and does not have any significant amount of community activity or development.  Perhaps once more AR6001 modules are available, this will change.&lt;&#x2F;p&gt;
&lt;p&gt;For Linux, there are several options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Atheros has released a driver that is available:  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;project&#x2F;showfiles.php?group_id=186068&quot;&gt;http:&#x2F;&#x2F;sourceforge.net&#x2F;project&#x2F;showfiles.php?group_id=186068&lt;&#x2F;a&gt;.  There are several issues with this driver in that it is written for a SDIO stack that will likely never be part of the mainstream kernel.&lt;&#x2F;li&gt;
&lt;li&gt;A driver is being developed as part of the OpenMoko project.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Embedded Works supplies Atheros based modules and development boards: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.embeddedworks.net&#x2F;wlan&#x2F;oem_sdio_80211g.html&quot;&gt;http:&#x2F;&#x2F;www.embeddedworks.net&#x2F;wlan&#x2F;oem_sdio_80211g.html&lt;&#x2F;a&gt;.    AR6001 development boards are also available from Cardaccess: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.cardaccess-inc.com&#x2F;products&#x2F;index.php?a=wlan_sdio&quot;&gt;http:&#x2F;&#x2F;www.cardaccess-inc.com&#x2F;products&#x2F;index.php?a=wlan_sdio&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;marvell&quot;&gt;Marvell&lt;&#x2F;h4&gt;
&lt;p&gt;The Marvell 88W8385 seems to be a very popular IC in WiFi modules available from a number of different companies.  OSS Linux drivers are in progress and are reportedly somewhat functional at this point, so it is probably just a matter of time before these devices are well supported in Linux.  This chipset&#x2F;driver is often referred to as “libertas”.  The SDIO stack being developed for the Linux mainline (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;242747&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;242747&#x2F;&lt;&#x2F;a&gt;) is where support for this device is being developed.&lt;&#x2F;p&gt;
&lt;p&gt;For Windows CE, it seems the only option is to get the drivers from Marvell, which is a very difficult and time consuming process – at least for low volume customers.  First you have to find a module reseller that can get you the source code from Marvell, and then the process takes about 3 months.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;other-options&quot;&gt;Other Options&lt;&#x2F;h4&gt;
&lt;p&gt;There are a number of other WiFi Silicon manufacturers and module vendors, but the driver options from them seem to be very limited in the form of binary only drivers that will only work with certain processors&#x2F;operating systems.  As noted before there is almost no hope of getting anyone to even talk with you if your volumes are low.  So your only hope is finding a module vendor that can do any driver work for a NRE fee, obtain the source from the silicon manufacturer, or use OSS drivers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The Embedded WiFi situation is changing fast, so by the time you read this, it is probably already out of date.  We are currently at the phase where it is very difficult to deeply embedded WiFi in low volume products.  I expect this will change during the next year.  Eventually, WiFi modules re-sellers will figure out that supplying hardware is just one side of the equation.  As things get more and more complex, the software availability and support is becoming the gating item.&lt;&#x2F;p&gt;
&lt;p&gt;Many thanks to James Nahra, Dave Anders, and Erik Strack for sharing information and their WiFi experiences with me over the past few months.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The correct way to add packages to an OpenEmbedded Image</title>
        <published>2007-08-30T00:00:00+00:00</published>
        <updated>2007-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/177/the-correct-way-to-add-packages-to-an-openembedded-image/"/>
        <id>https://bec-systems.com/177/the-correct-way-to-add-packages-to-an-openembedded-image/</id>
        
        <content type="html" xml:base="https://bec-systems.com/177/the-correct-way-to-add-packages-to-an-openembedded-image/">&lt;p&gt;&lt;strong&gt;Update 2007-10-14: use IMAGE_INSTALL in image recipe&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2007-10-22: a few corrections, added full path for include and comments&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2010-06-07: use recipes instead of packages directory&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As more and more OpenMoko developers are coming on-line, it is becoming obvious that my previous post (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;59&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;59&#x2F;9&#x2F;&lt;&#x2F;a&gt;) about adding packages to OpenEmbedded could use some improvements.  This post suggested using the DISTRO_EXTRA_RDEPENDS variable, which was intended to only be used in distro.conf files.  A better approach is to create a custom image recipe that includes the packages you want.  This article covers how to create a custom image recipe.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-are-the-problems-with-the-distro-extra-rdepends-approach&quot;&gt;What are the problems with the DISTRO_EXTRA_RDEPENDS approach?&lt;&#x2F;h3&gt;
&lt;p&gt;As detailed by Marcin Juszkiewicz in his blog post “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;blog.haerwu.biz&#x2F;2007&#x2F;08&#x2F;23&#x2F;why-using-of-distromachine-variables-in-localconf-is-wrong&#x2F;&quot;&gt;Why using of DISTRO&#x2F;MACHINE variables in local.conf is wrong&lt;&#x2F;a&gt;”, and from discussions with OE developers, the following issues surfaced:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You have to remember to rebuild task-base every time you update the DISTRO_EXTRA_RDEPENDS variable.&lt;&#x2F;li&gt;
&lt;li&gt;The image is no longer angstrom-console-image or whatever you have extended, so when asking for support, other developers do not realize exactly what you are building.  If it is a custom image, then that is obvious by the image name.&lt;&#x2F;li&gt;
&lt;li&gt;Changing DISTRO_EXTRA_RDEPENDS in local.conf requires that you bitbake reparse the entire recipe tree (which takes minutes).  Changing a custom image recipe only requires one file to be reparsed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;creating-a-custom-image-file&quot;&gt;Creating a custom image file&lt;&#x2F;h3&gt;
&lt;p&gt;Creating a custom image file is quite easy, and works much better than modifying DISTRO_EXTRA_RDEPENDS in your local.conf file.  A custom image is created by simply copying or including an image file closest to what we want to use, and then adding additional packages to IMAGE_INSTALL variable.  In the following example, we require angstrom-console-image.bb and extend it with a few lines:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;require recipes&#x2F;images&#x2F;console-image.bb

IMAGE_INSTALL += &amp;quot;\
        xset xserver-kdrive-fbdev xinit \
        kernel \
        kernel-module-mmc-block \
        kernel-module-mmc-core \
        kernel-module-pxamci \
        kernel-module-ac97-bus \
	&amp;quot;

export IMAGE_BASENAME = &amp;quot;my-custom-image&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note, this method requires your custom image file to be in the same location as the original image recipe. If you use a bbcollections overlay, then you may want to copy the original recipe.&lt;&#x2F;p&gt;
&lt;p&gt;Note the use of a full path specified in the require statement.  This allows you to have your custom image recipe in a bbcollections overlay, and bitbake will still find the required recipe in the main OE tree.&lt;&#x2F;p&gt;
&lt;p&gt;Thats it!  With the many advantages to this method, there is no reason not to create your own image recipes – it works better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Howto use a Git topic branch to maintain a patchset, and isolate problems</title>
        <published>2007-08-16T00:00:00+00:00</published>
        <updated>2007-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/247/howto-use-a-git-topic-branch/"/>
        <id>https://bec-systems.com/247/howto-use-a-git-topic-branch/</id>
        
        <content type="html" xml:base="https://bec-systems.com/247/howto-use-a-git-topic-branch/">&lt;p&gt;The more I use Git, the more I am really impressed with some of its capabilities.  What is Git?  Git is a very advanced distributed source code control system that can do some very neat things.  For the average developer using open source software, we are mainly concerned about maintaining patch sets (often called a topic branch).  Git includes a rebase capability that is very useful for a number of different operations related to maintaining a branch of code including moving a branch forward, moving a branch around on an upstream branch to look for breakage, and merging changesets to create patch files.  This article provides a brief overview of some of these operations and several tips.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-in-doubt-make-a-branch&quot;&gt;When in doubt, make a branch&lt;&#x2F;h3&gt;
&lt;p&gt;The most important concept to understand when working with Git is to get used to creating and destroying branches.  This is different than most other SCMs where all branches are stored on a central repository, and you don’t want to clutter the branch namespace.  With Git, get used to branching without even thinking about it.  For example, the following are the branches in a Git repository I use to maintain patch sets for the Compulab cm-x270:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; git branch
  cmx270
  cmx270_2.6.20
  cmx270_2.6.21
  cmx270_2.6.22
  master
  svs
* test
  v2.6.20_test
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Most of the names are self explanatory.   The cmx270 branch is where I track the latest kernel version.  The svs branch is for a customer platform based off the Compulab cm-x270.  To view the changes on any particular branch:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-log cmx270_2.6.22
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;an Git will start showing you a list of changes on that branch.  This works even if you are not working on that branch, so it is very handy for seeing what changes are in other branches.  With Git is also very easy to move changes between branches using &lt;em&gt;git-cherry-pick&lt;&#x2F;em&gt;.  For example, if we are working on the cmx270 branch, and we want to pull the 3rd changeset from the HEAD of the cmx270_2.6.22 branch into the cmx270 branch, we would do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-cherry-pick  cmx270_2.6.22~2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;git-is-really-good-at-maintaining-patch-sets&quot;&gt;Git is really good at maintaining patch sets&lt;&#x2F;h3&gt;
&lt;p&gt;Many developers use quilt to maintain patch sets.  Once you understand how Git works, Git is even better at maintaining patch sets.  Although there are some add-on tools available for maintaining patch files in a git repository like Patchy GIT and Stacked GIT, I’ve found that core Git works well enough.  Actually the Patchy GIT maintainer has quit working on Patchy GIT because core GIT now meets his needs.  The fundamentals are you simply export each Git commit as a patch using the git-format-patch command as shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-format-patch -o tmp&#x2F; master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;Produces the following files (all of the commits since the branch has left the master):
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;tmp&#x2F;0001-cm-x270-base2.patch
tmp&#x2F;0002-cm-x270-match-type.patch
tmp&#x2F;0003-cm-x270-ide.patch
tmp&#x2F;0004-cm-x270-it8152.patch
tmp&#x2F;0005-cm-x270-pcmcia.patch
tmp&#x2F;0006-ramdisk_load.patch
tmp&#x2F;0007-mmcsd_large_cards-r0.patch
tmp&#x2F;0008-cm-x270-nand-simplify-name.patch
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pretty slick!  HEAD~8 means to back up 8 revisions from the current HEAD and then start outputting changes as patch files.  The name of the patch file is the commit comment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;moving-your-patch-set-forward-in-time&quot;&gt;Moving your patch set forward in time&lt;&#x2F;h3&gt;
&lt;p&gt;If you are maintaining a patch set for the Linux kernel, you might want to move your patchset up to the latest version for testing, and also maintain patchsets for each stable version of the kernel.  Lets say we already have a patch set for the 2.6.20 version.  The first thing we need to do is create a branch.  In this example, I am maintaining a patch set for the Compulab cm-x270 computer module.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-branch cmx270_2.6.20 v2.6.20  (branch name, tag name in repository)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;git-checkout cmx270_2.6.20
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, I would manually apply each patch, and then commit each patch as its own changeset.  Now, I want to move the changeset forward to kernel version 2.6.21.  The easiest way to do this is create a new branch, and simply rebase your patchset to the new kernel version.  Make sure you create a new branch first, or your existing branch will be moved!&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-checkout -b cmx270_2.6.21 cmx270_2.6.20
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;git-rebase --onto v2.6.21 master (tag point to relocate branch, upstream branch)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The upstream branch is required to be specified so that Git knows where our branch changes start – specifically where the cmx270_2.6.21 branch diverges from the master branch.&lt;&#x2F;p&gt;
&lt;p&gt;There may be a few things to clean up along the way if changes don’t apply cleanly.  The most critical thing to know is that if you want to skip a patch, you must run “&lt;em&gt;git-reset --hard&lt;&#x2F;em&gt;” before running “&lt;em&gt;git-rebase --skip”&lt;&#x2F;em&gt;.  This is often handy if you have an especially troublesome patch that you don’t want to apply now.  You can skip it and then cherry-pick it later.  Otherwise the process is fairly straightforward.  After you are finished, you can now export a set of patch files that can be applied to the 2.6.21 kernel.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bisecting-the-master-branch-to-determine-when-things-broke&quot;&gt;Bisecting the master branch to determine when things broke&lt;&#x2F;h3&gt;
&lt;p&gt;You may run into a situation where something broke on the main branch, and you don’t know where.  Most of the time, you would just run &lt;em&gt;git-bisect&lt;&#x2F;em&gt; to do a binary search to find where things broke.  This does not work so well if the platform you are testing is not supported in the main branch – the changes in your topic branch are required to make the system run.  Once again, &lt;em&gt;git-rebase&lt;&#x2F;em&gt; to the rescue.  The first thing we must do is find the mid-point between the known good and bad points.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-rev-list --bisect v2.6.20 v2.6.21
13f7e5acc8b329080672c13f05f252ace5b79825
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, rebase out changes to the above rev and test.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git rebase --onto 13f7e5acc8b329080672c13f05f252ace5b79825 master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The build failed, so now we have a new “bad” point and can continue our binary search.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-rev-list --bisect v2.6.20 13f7e5acc8b329080672c13f05f252ace5b79825
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you can build working kernels from the main tree, then you can directly use git-bisect – another good reason to get your changes into the mainstream source, but this is not always possible.&lt;&#x2F;p&gt;
&lt;p&gt;Another option for doing this type of binary search is to use git-bisect, and then cherry pick your changes at each bisect point.  It may also be possible to use git-merge, but I have not figured out how yet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;That is it for now.  Git is very useful for maintaining multiple patch sets for different versions of an open source project, and is just another thing that makes working with open source projects a real pleasure.  Future articles will cover how to further manipulate patches such as how to combine two patch files.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux 2.6.22 for the Compulab cm-x270</title>
        <published>2007-08-13T00:00:00+00:00</published>
        <updated>2007-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/168/linux-2-6-22-for-the-compulab-cm-x270/"/>
        <id>https://bec-systems.com/168/linux-2-6-22-for-the-compulab-cm-x270/</id>
        
        <content type="html" xml:base="https://bec-systems.com/168/linux-2-6-22-for-the-compulab-cm-x270/">&lt;p&gt;I just completed porting the cm-x270 Linux kernel patches to the 2.6.22 kernel.  Kernel build is available in OpenEmbedded.  Patches are available in the OE tree:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;compulab-pxa270-2.6.22&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;compulab-pxa270-2.6.22&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Shortly I will be making 2.6.22 the default kernel for the cm-x270 in OpenEmbedded and posting instructions on how to use JFFS2 with the NAND flash on the cm-x270.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Design tips for your embedded Linux product</title>
        <published>2007-07-20T00:00:00+00:00</published>
        <updated>2007-07-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/159/design-tips-for-your-embedded-linux-product/"/>
        <id>https://bec-systems.com/159/design-tips-for-your-embedded-linux-product/</id>
        
        <content type="html" xml:base="https://bec-systems.com/159/design-tips-for-your-embedded-linux-product/">&lt;p&gt;When designing a system that runs embedded Linux, there are number of things you can do to make your life a lot easier and provide for future expansion to cover cases you did not anticipate.  Following these simple guidelines can drastically improve the efficiency of developing the system, and troubleshooting problems during field testing, and provide the flexibility needed in todays products.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-have-a-dedicated-serial-console&quot;&gt;#1 Have a dedicated serial console&lt;&#x2F;h3&gt;
&lt;p&gt;This is the single most important interface to provide.  A serial console is your gateway into the system, and allows you at any time to poke around at the internals of the system, debug problems, run applications, change configuration, etc.  A serial console does not have to be a big DB9 connector accessible outside the system.  It can can be a simple 3 pin header and you make a special cable to connect to a PC.  Also, do put the RS232 level translators on the board.  This saves so much hassle during the development and testing cycle.  You can always not populate them later, but you will probably find that the debug console is so useful, you will leave it in – even in production.&lt;&#x2F;p&gt;
&lt;p&gt;Another consideration is to make sure you use a serial port provided by the processor if possible.  The advantage of this is very little hardware has to be working for the serial console to work.  If you use a serial port off an external UART, then the bus interface between the processor and the UART, the UART and the processor need to be working.  If something is wrong with the system, you are less likely to get debug messages out the serial console which will help you debug the system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-implement-a-usb-host-port&quot;&gt;#2 Implement a USB Host port&lt;&#x2F;h3&gt;
&lt;p&gt;A USB host port is so useful it should be considered for about any system.  Some of the things USB can be used for include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;keyboard and mouse if you are designing a display based system&lt;&#x2F;li&gt;
&lt;li&gt;USB networking&lt;&#x2F;li&gt;
&lt;li&gt;Wifi networking&lt;&#x2F;li&gt;
&lt;li&gt;extra serial ports&lt;&#x2F;li&gt;
&lt;li&gt;WAN modems&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Many embedded processors that can run Linux include a USB Host interface, so assuming you have one of these, it is very cheap to provide this interface as it only requires two wires, and a 5V power supply.&lt;&#x2F;p&gt;
&lt;p&gt;Once again, you don’t have to put a full size USB connector in your device – a simple header wired to a connector might work in most situations.&lt;&#x2F;p&gt;
&lt;p&gt;I can’t begin to describe how useful a USB keyboard was on a recent touchscreen based product.  The product is used in agricultural vehicles, so anytime in the field we can connect a USB keyboard and look at logs, run commands, and other operations that are very difficult to do though a touch interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-implement-a-network-interface&quot;&gt;#3 Implement a Network Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Working on any Linux system is very painful without a networking interface.  Even if you don’t plan to use Ethernet in the final product, make sure a networking interface is available for development.  Some reasons why a network interface is critical:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;can easily log into the system remotely for development and debugging&lt;&#x2F;li&gt;
&lt;li&gt;easily copy files to and from the device quickly&lt;&#x2F;li&gt;
&lt;li&gt;install software updates easily during the development process&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Trust me on this one.  The neat thing about Linux, is if you have a USB Host interface, and a reasonably modern kernel, you can use off-the-shelf USB-&amp;gt;Network devices for Ethernet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-provide-a-fast-way-for-the-bootloader-to-download-sw-updates&quot;&gt;#4 Provide a fast way for the bootloader to download SW updates&lt;&#x2F;h3&gt;
&lt;p&gt;This is important.  Don’t depend on JTAG or a serial port for programming large OS images.  Some options for BL image download include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;network (preferred)&lt;&#x2F;li&gt;
&lt;li&gt;MMC&#x2F;SD&lt;&#x2F;li&gt;
&lt;li&gt;USB Client&lt;&#x2F;li&gt;
&lt;li&gt;USB Host (using a USB Mass storage device)&lt;&#x2F;li&gt;
&lt;li&gt;PCMCIA&#x2F;CF&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The good news is if you did steps #2 &amp;amp; #3, this might be taken care of – just make sure you check what the bootloader actually supports.  One project I worked on recently only had a serial interface and a USB client interface that the BL did not support.  We ended up creating a mini rootfs that included just enough smarts to download the main rootfs over the USB Client interface.  So, there are ways to work around some of these issues, but its a lot easier if you do a little planning up front.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;There is a lot to be said for using industry standard interfaces and components like Linux, USB, and Ethernet.   When you design a system using standard building blocks, your product will have the flexibility to implement features you never thought of when the product was originally designed.  And, your development and testing will go so much smoother.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Open JTAG debugging tool for the PXA270</title>
        <published>2007-07-10T00:00:00+00:00</published>
        <updated>2007-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/242/open-jtag-debugging-tool-for-the-pxa270/"/>
        <id>https://bec-systems.com/242/open-jtag-debugging-tool-for-the-pxa270/</id>
        
        <content type="html" xml:base="https://bec-systems.com/242/open-jtag-debugging-tool-for-the-pxa270/">&lt;p&gt;Looking for a low cost, high functionality JTAG solution for the PXA270?  As of several weeks ago, the openocd project now works with the Intel&#x2F;Marvell PXA270 processor.  There are a number of USB based JTAG debuggers available for under $100, so the cost is minimal.  This article provides a brief overview of JTAG, suggestions for your hardware design, and how to use OpenOCD (Open On-chip-debugger) with the PXA270.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openocd&quot;&gt;OpenOCD&lt;&#x2F;h3&gt;
&lt;p&gt;Over the past 8 years, I’ve used a number of JTAG solutions for programming and debugging embedded processor systems.  At the low end, there are JTAG solutions for flash programming only that just wiggle pins on a PC parallel port which in turn wiggle pins on the scan chain of the processor.  This way of doing things works, but is very slow because you have to fabricate the bus cycles in software and clock the entire jtag chain just to change the state of one pin.  The jtag tools from the openwince project on Sourceforge fall into this category.&lt;&#x2F;p&gt;
&lt;p&gt;More advanced JTAG tools use the debugging capability of a processor to speed up flash programming and add debugging features.  This typically involves downloading a tiny bit of code into the cache or internal SRAM in the CPU.  This bit of code then can receive blocks of data or instructions and run bus cycles directly through the memory controller in the device.  This makes flash programming very fast as most of the work is being done by the CPU, instead of manually controlling CPU pins using a jtag chain.&lt;&#x2F;p&gt;
&lt;p&gt;In past years, there have been various attempts at creating an open source JTAG solution, but none of them have gotten very far.  When I had a project that needed to get done quickly, I simply bought or upgraded a BDI2000 debugger – which is an excellent tool.  The OpenOCD project now provides much of the same functionality as a BDI2000, but as in the case of the PXA270, it sometimes takes some work to get it all working.&lt;&#x2F;p&gt;
&lt;p&gt;OpenOCD was created by Dominic Rath as part of a diploma thesis (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openocd.berlios.de&#x2F;web&#x2F;&quot;&gt;http:&#x2F;&#x2F;openocd.berlios.de&#x2F;web&#x2F;&lt;&#x2F;a&gt;).  It provides support for a wide range of target processors and JTAG debuggers.  OpenOCD includes functionality for On-Chip Debugging, In-System Programming, and Boundary-Scan Testing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hardware-design-considerations&quot;&gt;Hardware design considerations&lt;&#x2F;h3&gt;
&lt;p&gt;Although openocd has worked with other Xscale parts for some time, functionality for the PXA270 has not worked until recently.  The primary reason for this is the way the power supplies are sequenced in most PXA270 designs.  There is one supply to the PXA270 that is always on (VCC_BATT).  All of the other supplies are often kept off until reset to the processor is de-asserted and the SYS_EN and PWR_EN signals go active.  Because of this, some special considerations need to be taken during the sequencing of the reset signals, and the setting of the hold_rst bit in the PXA270 DCSR register.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure you power the JTAG connection (Pin #1 of your JTAG connector) with VCC_BATT or some power that is always active.  If you power the JTAG connector with a power supply that is controlled by the SYS_EN or PWR_EN signal, then you will loose JTAG power during the connection process and things obviously will not work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jtag-debugger-hardware&quot;&gt;JTAG Debugger Hardware&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the JTAG debugger debuggers used with OpenOCD are based on the FTDI FT2232 USB chip.   The debugger I used is the arm-usb-ocd device from Olimex.  At a cost of $80, you can’t afford not to have one.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;olimex-1.jpg&quot; alt=&quot;olimex&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openocd-installation&quot;&gt;OpenOCD Installation&lt;&#x2F;h3&gt;
&lt;p&gt;OpenOCD can use two different libraries that provide access to the FTDI chip: an open source library named &lt;em&gt;libftdi&lt;&#x2F;em&gt;, and a closed source library from FTDI named &lt;em&gt;libftd2xx&lt;&#x2F;em&gt;.  I could not get the opensource libftdi library to work, so I suggest you use the FTDI library for now.  Otherwise, installation is pretty straightforward.  Find yourself a reasonably modern Linux computer and follow instructions on the following page: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openfacts.berlios.de&#x2F;index-en.phtml?title=Building_OpenOCD&quot;&gt;http:&#x2F;&#x2F;openfacts.berlios.de&#x2F;index-en.phtml?title=Building_OpenOCD&lt;&#x2F;a&gt; .  Make sure you use the &lt;em&gt;--enable-ft2232_ftd2xx&lt;&#x2F;em&gt; option when running &lt;em&gt;configure&lt;&#x2F;em&gt;.  On Ubuntu 7.04:&lt;&#x2F;p&gt;
&lt;p&gt;Install the FTDI library:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;wget http:&#x2F;&#x2F;www.ftdichip.com&#x2F;Drivers&#x2F;D2XX&#x2F;Linux&#x2F;libftd2xx0.4.13.tar.gz&lt;&#x2F;li&gt;
&lt;li&gt;mkdir libftd2xx; cd libftd2xx; tar -xzf ..&#x2F;libftd2xx0.4.13.tar.gz&lt;&#x2F;li&gt;
&lt;li&gt;sudo cp *.h &#x2F;usr&#x2F;local&#x2F;include&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;sudo cp libftd2xx.so.0.4.13 &#x2F;usr&#x2F;local&#x2F;lib&lt;&#x2F;li&gt;
&lt;li&gt;cd &#x2F;usr&#x2F;local&#x2F;lib&#x2F;; ln -s libftd2xx.so.0.4.13 libftd2xx.so; sudo ln -s libftd2xx.so.0.4.13 libftd2xx.so.0&lt;&#x2F;li&gt;
&lt;li&gt;cd &#x2F;usr&#x2F;lib; ln -s &#x2F;usr&#x2F;local&#x2F;lib&#x2F;libftd2xx.so.0.4.13 libftd2xx.so.0&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Install OpenOCD:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;sudo apt-get install build-essential&lt;&#x2F;li&gt;
&lt;li&gt;sudo apt-get install automake&lt;&#x2F;li&gt;
&lt;li&gt;sudo apt-get install autoconf&lt;&#x2F;li&gt;
&lt;li&gt;svn checkout svn:&#x2F;&#x2F;svn.berlios.de&#x2F;openocd&#x2F;trunk openocd&lt;&#x2F;li&gt;
&lt;li&gt;cd openocd&lt;&#x2F;li&gt;
&lt;li&gt;.&#x2F;configure  &lt;em&gt;--enable-ft2232_ftd2xx&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;make&lt;&#x2F;li&gt;
&lt;li&gt;sudo make install&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;openocd-configuration&quot;&gt;OpenOCD Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;OpenOCD is configured using a configuration file.  An example is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# config for Intel PXA270
# not, as of 2007-06-22, openocd only works with the
# libftd2xx library from ftdi.  libftdi does not work.

telnet_port	3333
gdb_port	4444

interface ft2232
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15BA 0x0003
ft2232_device_desc &amp;quot;Olimex OpenOCD JTAG&amp;quot;
jtag_speed 0
# set jtag_nsrst_delay to the delay introduced by your reset circuit
# the rest of the needed delays are built into the openocd program
jtag_nsrst_delay 260
# set the jtag_ntrst_delay to the delay introduced by a reset circuit
# the rest of the needed delays are built into the openocd program
jtag_ntrst_delay 0

#use combined on interfaces or targets that can&amp;#39;t set TRST&#x2F;SRST separately
reset_config trst_and_srst separate

#jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 7 0x1 0x7f 0x7e

#target configuration
daemon_startup reset

target xscale little reset_halt 0 pxa27x

# maps to PXA internal RAM.  If you are using a PXA255
# you must initialize SDRAM or leave this option off
working_area 0 0x5c000000 0x10000 nobackup

run_and_halt_time 0 30

#flash bank &amp;lt;driver&amp;gt; &amp;lt;base&amp;gt; &amp;lt;size&amp;gt; &amp;lt;chip_width&amp;gt; &amp;lt;bus_width&amp;gt;
# works for P30 flash
flash bank cfi 0x00000000 0x1000000 2 4 0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;programming-flash&quot;&gt;Programming Flash&lt;&#x2F;h3&gt;
&lt;p&gt;After OpenOCD is installed, copy the above config file contents to a file name openocd.cfg, and run openocd in the same directory as your configuration file.&lt;&#x2F;p&gt;
&lt;p&gt;Currently, there is an issue in that the openocd is expecting a debug handler file at a specific relative path from the openocd binary.  The easiest way to get around this for now is to to run openocd from the src directory in the openocd source code.&lt;&#x2F;p&gt;
&lt;p&gt;If you get the following message:  Error:   ft2232.c:1338 ft2232_init_ftd2xx(): unable to open ftdi device: 2, there is a permissions problem with the USB device.  To get around this, run openocd using sudo, or add the appropriate rules to udev to allow the usb device to be used by any user.&lt;&#x2F;p&gt;
&lt;p&gt;OpenOCD runs as a daemon waiting for telnet or GDB connections.  After openocd starts, you can connect to it by running the following command:  telnet localhost 3333&lt;&#x2F;p&gt;
&lt;p&gt;At this point you should be presented with a OpenOCD prompt.  The following is an example of how to program a bootloader into flash memory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; flash probe 0
flash &amp;#39;cfi&amp;#39; found at 0x00000000
&amp;gt; flash protect 0 0 5 off
cleared protection for sectors 0 through 5 on flash bank 0
&amp;gt; flash erase 0 0 5 off
erased sectors 0 through 5 on flash bank 0 in 4s 615249us
&amp;gt; flash write 0 &#x2F;build&#x2F;tmp&#x2F;u-boot-holon.bin 0
wrote 121832 byte from file &#x2F;build&#x2F;tmp&#x2F;u-boot-holon.bin to flash bank 0 at offset 0x00000000 in 6s 138592us (19.381735 kb&#x2F;s)
&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;debugging&quot;&gt;Debugging&lt;&#x2F;h3&gt;
&lt;p&gt;In this example, OpenOCD waits for GDB connections on port 4444.  To debug code running on the target, you would use gdb in the same way you would use a BDI2000, or most any other hardware debugger with GDB.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;OpenOCD is a robust, full-featured JTAG debug solution that supports many processors and low cost JTAG debuggers.  There are still a few rough edges to clean up with PXA270 support, but OpenOCD is already a very useful tool for embedded software development.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to control the cable nightmare</title>
        <published>2007-06-20T00:00:00+00:00</published>
        <updated>2007-06-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/235/how-to-control-the-cable-nightmare/"/>
        <id>https://bec-systems.com/235/how-to-control-the-cable-nightmare/</id>
        
        <content type="html" xml:base="https://bec-systems.com/235/how-to-control-the-cable-nightmare/">&lt;p&gt;Do you ever wonder if there is a better way to manage cables in your lab?  I typically have have 5-10 embedded systems on the bench powered up at any give time.  When you start thinking of all the cables required to connect these systems (every one requires at least power, serial console, and network), it starts to add up.  I recently ran across a product called snaketray (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;snaketray.com&#x2F;products&#x2F;wall.html&quot;&gt;http:&#x2F;&#x2F;snaketray.com&#x2F;products&#x2F;wall.html&lt;&#x2F;a&gt; ) and decided it might be the solution to my rats-nest of cables.  This article includes a few pictures of my implementation, and some ideas.  I’m quite pleased with the result and have high hopes that I’ll keep my sanity for a while longer.&lt;&#x2F;p&gt;
&lt;p&gt;I’m sure there are many solutions to cable management.  The IT folks managing racks of computers no doubt have lots of good solutions.  There are lots of different cable ties available, etc.  But, the needs of a developer are a little different in that you need a solution that can easily be changed.  You need something that is not permanent where you can quickly add, change, and re-route cables as needed.  Most cable management solutions are more permanent solutions not designed for flexibility.  Then I read the following article: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;articles&#x2F;BionicOffice.html&quot;&gt;http:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;articles&#x2F;BionicOffice.html&lt;&#x2F;a&gt;.  It occurred to me that snaketray might be the perfect solution for an embedded systems development lab.  The idea of snaketray is very simple as shown in the picture below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_1-1.jpg&quot; alt=&quot;snaketray_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I installed two runs about 1.5 feet above my lab work space.  There are power strips along the back of each lab surface.  All cables now run in the snaketray.  The idea is cables go straight into the snaketray and exit exactly where the are needed.  If the cable is too long, I loop it back in the snaketray.  The result is pretty amazing when you compare it to what it was before.  My wife is not real impressed with how it looks – apparently she has not spend enough time under tables untangling cables :-)&lt;&#x2F;p&gt;
&lt;p&gt;Some of the benefits I’ve discovered so far:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;even though it still looks pretty messy, I’m finding it very easy to pull cables out of the tray and re-route them – even network cables which are notorious for getting hung up due to the little plastic clip on the connector.  I think the reason is the cables are always running orthogonal – in the tray and the come out at a 90 degree angle where they are needed.  So if cables are not crossing each other they do not get tangled.&lt;&#x2F;li&gt;
&lt;li&gt;bench space is not used for cables, so I have lots of space for more systems&lt;&#x2F;li&gt;
&lt;li&gt;I’ll be more likely to try builds routinely on more targets.  One of my goals is to routinely do OpenEmbedded builds for a variety of embedded systems to keep my finger on the OE pulse, and help with QA.  Obviously crawling around on the floor untangling cables to connect various systems is a negative motivator for such activities.&lt;&#x2F;li&gt;
&lt;li&gt;I have a place to put cables when I’m not using them – just put them in the tray.  Before, they were left on my lab bench taking space, or falling on the floor.  Now I have a few extra network and serial cables waiting in the tray for when I need them.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The bottom line is this makes me more efficient at what I do, so that I can better serve my customers and the projects I work on.  I imagine snaketray would also be very useful in factory setups and other situation where you routinely need to change cabling.&lt;&#x2F;p&gt;
&lt;p&gt;What you you found that works in your lab?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_2-1.jpg&quot; alt=&quot;snaketray_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_3-1.jpg&quot; alt=&quot;snaketray_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_4-1.jpg&quot; alt=&quot;snaketray_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Atmel AT32AP7000 development board review</title>
        <published>2007-06-09T00:00:00+00:00</published>
        <updated>2007-06-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/162/atmel-at32ap7000-development-board-review/"/>
        <id>https://bec-systems.com/162/atmel-at32ap7000-development-board-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/162/atmel-at32ap7000-development-board-review/">&lt;p&gt;I recently purchased an Atmel NGW100 development board which includes an Atmel AT32AP7000 CPU.  This CPU is based on the new Atmel AVR32 architecture, and is capable of running full Linux.  This review covers the basics of this development board, the AVR32 architecture, options for building Linux for this system, as well as opinions on how a new architecture can succeed in a field of well established architectures like ARM and MIPS.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-is-avr32&quot;&gt;What is AVR32?&lt;&#x2F;h3&gt;
&lt;p&gt;The AVR32 architecture defined by Atmel is a 32-bit RISC load&#x2F;store architecture. There are several different versions of the core.  Atmel currently supplies two classes of AVR32 cpus:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;UC3 Flash MCUs - low end devices with integrated RAM and flash, no MMU, and look similar in capability to ARM7 microcontroller type devices.&lt;&#x2F;li&gt;
&lt;li&gt;AP7 Application Processors - faster devices, include MMU, seem similar in capability and speed to ARM9 application processors such as Atmel’s AT92SAM devices.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As I am most interested in CPUs that can run Linux, this review will focus on the AP7 (AVR32 AP) class devices.&lt;&#x2F;p&gt;
&lt;p&gt;It seems that AVR32 is Atmel’s answer to ARM Cortex.  Some features of the AP7 devices:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;good code density&lt;&#x2F;li&gt;
&lt;li&gt;DSP instructions that execute in a single cycle&lt;&#x2F;li&gt;
&lt;li&gt;Full MMU&lt;&#x2F;li&gt;
&lt;li&gt;Instruction and Data caches&lt;&#x2F;li&gt;
&lt;li&gt;SIMD extensions&lt;&#x2F;li&gt;
&lt;li&gt;dynamic branch prediction&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The MMU in the AP7 devices is interesting in that page tables are handled in software similar to a MIPS device.  In a ARM CPU, the page tables are located in physical RAM and are strictly defined by the ARM architecture and page faults are handled in hardware.  With MIPS (at least some devices) and AVR32, the MMU basically consists of a TLB (Translation Lookaside Buffer) that maps virtual addresses to physical address.  As the TLB is limited in size, any misses are handled in software.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ngw100-development-board&quot;&gt;NGW100 Development board&lt;&#x2F;h3&gt;
&lt;p&gt;The NGW100 development board is available from a number of distributors (including Digikey) for about $70.  The board includes the following major components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Atmel AT32AP7000 CPU&lt;&#x2F;li&gt;
&lt;li&gt;32MB of SDRAM (MT48LC16M16A2)&lt;&#x2F;li&gt;
&lt;li&gt;8MB Parallel NOR Flash (AT49BV642D-70TU)&lt;&#x2F;li&gt;
&lt;li&gt;8MB Serial NOR Flash (AT45DB642D)&lt;&#x2F;li&gt;
&lt;li&gt;2 Ethernet ports&lt;&#x2F;li&gt;
&lt;li&gt;SD&#x2F;MMC slot&lt;&#x2F;li&gt;
&lt;li&gt;RS232 port&lt;&#x2F;li&gt;
&lt;li&gt;USB Client port&lt;&#x2F;li&gt;
&lt;li&gt;Microcontroller for board control (ATtiny24-20SSU)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;ngw100-1.jpg&quot; alt=&quot;ngw100&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-support&quot;&gt;Linux Support&lt;&#x2F;h3&gt;
&lt;p&gt;Atmel is directly supporting the development effort for the AP7 processors.  They seem to be doing it right in that they are pushing support directly into the mainstream kernel.  Currently, Atmel provide patches for GCC and uClibc.  There is already efforts underway to provide AVR32 support in Openembedded, which will enable developers to quickly build full featured Linux distributions for AVR32 based products.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;It will be interesting to see how the AVR32 based products work out.  On one hand, one could argue that a custom architecture like AVR32 can’t succeed as it does not have an extensive ecosystem of tool vendors in place like ARM and MIPS.  But, the availability of open source software such as GCC and Linux is rapidly lowering the barrier to entry for creating tools for new architectures.  No longer do you need to wait for commercial tool vendors to provide software support.  The model for software development is changing.&lt;&#x2F;p&gt;
&lt;p&gt;In comparison to Atmel’s AT91SAM parts, its difficult initially to see what the AVR32 parts offer over the SAM parts.  For one, they are lacking a USB Host port which is becoming increasingly important to have in embedded Linux systems.   Perhaps they offer other advantages such as lower cost and power.  As we gain experience with these parts, I’m sure we’ll find applications where they are an excellent fit.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Embedded Industry Transformation</title>
        <published>2007-06-09T00:00:00+00:00</published>
        <updated>2007-06-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/82/the-embedded-industry-transformation/"/>
        <id>https://bec-systems.com/82/the-embedded-industry-transformation/</id>
        
        <content type="html" xml:base="https://bec-systems.com/82/the-embedded-industry-transformation/">&lt;p&gt;I just ran across an interesting article written by Doug Gaff titled “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.linuxdevices.com&#x2F;articles&#x2F;AT2891246233.html&quot;&gt;Is the embedded industry dead?&lt;&#x2F;a&gt;”.  The article points out the transformation that is happening in the “embedded” industry.  For many systems, we are no longer constrained by minimal resources (&#x2F;web&#x2F;content&#x2F;view&#x2F;67&#x2F;9&#x2F;).  Embedded Systems are no longer isolated systems, but parts of larger systems.&lt;&#x2F;p&gt;
&lt;p&gt;A few of my own observations:&lt;&#x2F;p&gt;
&lt;p&gt;There is more to modern embedded systems than control and logic.  We now have to worry about data.  In the past the task might be to get a microcontroller to run a state machine, control motors, etc.  Today, we need to present a calendar to the user through a web interface, collect information about the location of the Sun, upload statistics to a remote server, support a rich GUI application on a VGA color display.  The control aspect is suddenly the small part of the problem, and managing data is often the primary concern.&lt;&#x2F;p&gt;
&lt;p&gt;Embedded system development now encompasses many disciplines including OS development, web services, advanced application development in high level languages, and the traditional hardware debugging and low level coding tasks.  It is becoming less about writing code and more about integration of the right pieces.  As Embedded Systems become more complex, access to specialized knowledge is becoming more important.  There is just too much for one person (or even one company) to know.  Companies developing competitive products in the future will be the ones who have access to experts.
Is your company taking advantage of this transformation?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Can you afford not to use Linux in your product?</title>
        <published>2007-05-29T00:00:00+00:00</published>
        <updated>2007-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/156/can-you-afford-not-to-use-linux-in-your-product/"/>
        <id>https://bec-systems.com/156/can-you-afford-not-to-use-linux-in-your-product/</id>
        
        <content type="html" xml:base="https://bec-systems.com/156/can-you-afford-not-to-use-linux-in-your-product/">&lt;p&gt;How much does hardware capable of running Linux cost?  Recently, I priced components for a fairly minimal system.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Atmel AT91SAM9260 (&amp;lt; $10)&lt;&#x2F;li&gt;
&lt;li&gt;32MBytes of SDRAM ($6)&lt;&#x2F;li&gt;
&lt;li&gt;256MBytes of NAND flash ($6)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These are prices for relatively low volumes on the order of 1000 pieces.  So, you can get a processor, RAM, and flash that is more than capable of running Linux for about $20.  Think about the possibilities.  The AT91SAM9260 is a rather impressive part and includes interfaces for about anything including USB, SD&#x2F;MMC, Ethernet, and the list goes on.  It also includes that capability to boot from NAND flash which eliminates a dedicated NOR boot flash and reduces cost.  If you don’t want to do a full processor design, processor modules can be obtained for &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;156&#x2F;can-you-afford-not-to-use-linux-in-your-product&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;less than $100&lt;&#x2F;a&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;So, at this price you have to ask: can I afford not to embed Linux in my product?  Can I afford not to take advantage of standard interfaces like Ethernet and USB?  Can I afford not to take advantage of 1000’s of high quality applications and drivers?  Can I afford to not implement a system with virtually &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;156&#x2F;can-you-afford-not-to-use-linux-in-your-product&#x2F;content&#x2F;view&#x2F;67&#x2F;9&#x2F;&quot;&gt;unlimited storage&lt;&#x2F;a&gt; and capability for expansion?  Think about this carefully because your competitors are.  Have questions or need help getting started?  &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;156&#x2F;can-you-afford-not-to-use-linux-in-your-product&#x2F;component&#x2F;option,com_contact&#x2F;Itemid,3&#x2F;&quot;&gt;Contact us&lt;&#x2F;a&gt; – we can help.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Is Linux ready for real-time applications?</title>
        <published>2007-05-12T00:00:00+00:00</published>
        <updated>2007-05-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/152/is-linux-ready-for-real-time-applications/"/>
        <id>https://bec-systems.com/152/is-linux-ready-for-real-time-applications/</id>
        
        <content type="html" xml:base="https://bec-systems.com/152/is-linux-ready-for-real-time-applications/">&lt;p&gt;Have you ever wondered about the real-time response of Linux and how well it performs?  I recently developed a system where I had the requirement to send a packet of data out a serial port every 30ms.  This article describes how stock Linux can be used to accomplish this and solutions to several problems I encountered.  There are several concepts that need to be understood such as how to set a Linux process to real-time,  and kernel preemption.&lt;&#x2F;p&gt;
&lt;p&gt;All of the work referenced in this article was done on a &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;Compulab cm-x270&lt;&#x2F;a&gt; system which is based on the PXA270 ARM processor.  Before utilizing any real-time optimizations, the packets sent out the serial port where anything but consistent.  There was a significant amount of jitter in the packet timing and occasionally we would see delays of up to several seconds.  Obviously this was not good enough.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;real-time-process-priority&quot;&gt;Real Time Process Priority&lt;&#x2F;h3&gt;
&lt;p&gt;The first step was to partition the application into several threads, and give the serial communication thread a priority of real time.  Linux supports several scheduling policies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SCHED_OTHER: default universal time-sharing scheduler policy used by most processes.&lt;&#x2F;li&gt;
&lt;li&gt;SCHED_BATCH: intended for “batch” style execution&lt;&#x2F;li&gt;
&lt;li&gt;SCHED_FIFO: First In-First Out scheduling. Can only be used with static priorities higher than 0.  A SCHED_FIFO process will always run before a SCHED_OTHER or SCHED_BATCH process.  A SCHED_FIFO process runs until it is blocked by an I&#x2F;O request, or is preempted by a higher priority process.&lt;&#x2F;li&gt;
&lt;li&gt;SCHED_RR: Round Robin scheduling.  SCHED_RR is similar to SCHED_FIFO, except the process will only run for a maximum time quantum if there is a process of equal priority waiting to be run.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Practically, in a simple system there is really not much difference between SCHED_FIFO and SCHED_RR as you will typically only have at most a couple real time processes and you will probably assign them different priorities.&lt;&#x2F;p&gt;
&lt;p&gt;The sched_setscheduler() system call can be used to set a process or thread priority – see the Linux man pages for more details.&lt;&#x2F;p&gt;
&lt;p&gt;After setting the communication thread to real time, there was a noticeable improvement in the packet scheduling, but there was still way too much jitter and the occasional several seconds of silence with no packets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preemptible-kernel&quot;&gt;Preemptible Kernel&lt;&#x2F;h3&gt;
&lt;p&gt;After some experimentation, and reading, it was suspected that the NAND flash driver in the system was locking the kernel for long periods of time.  With older Linux kernels, the kernel was not preemptible.  Any process running in the kernel had to finish before something else could run.  Recent 2.6 Linux kernel include an option to enable Kernel Preemption (CONFIG_PREEMPT).   This allows a real-time process to preempt the system even if it is running in kernel space.   After enabling the CONFIG_PREEMPT option in the kernel, the scheduling of packets was very consistent most of the time with almost no perceptible jitter.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;be-careful-what-you-put-in-your-real-time-thread&quot;&gt;Be careful what you put in your real-time thread&lt;&#x2F;h3&gt;
&lt;p&gt;Now the system was running fairly well, but we still noticed at system startup that there were still some long delays between packets.  It turns out the application was writing log messages to a file on NAND flash in the real-time thread using the standard glib logging functions.  At system startup, the NAND driver blocks for long periods of time (up to several seconds).  After the system has been running for a short time, this went away.  The solution in this case was to send any logging messages from the communication thread to a separate normal priority logging thread.  This fixed any remaining issues and the packet scheduling is now rock solid all the time.  The leads to an fundamental real-time concept which seems very obvious in hindsight:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Do not access any I&#x2F;O (such as storage or network interfaces) that may block for long periods of time****in a real time process.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Although we had designed all the primary I&#x2F;O to be handled this way, we had not given any consideration to log file writes, which are an important part of any program.&lt;&#x2F;p&gt;
&lt;p&gt;The glib library provides several very nice mechanisms for sending data between threads.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-real-time&quot;&gt;Linux Real-time&lt;&#x2F;h3&gt;
&lt;p&gt;With improvements in the 2.6 Linux kernel, Linux works very well for some real-time applications.  While I would still be very careful in using Linux for critical, hard-real time requirements due to its overall complexity, Linux works very well for multi-media, communication, and data acquisition systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND Flash is almost &quot;free&quot; and what it means for Embedded Systems</title>
        <published>2007-02-26T00:00:00+00:00</published>
        <updated>2007-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/149/nand-flash-is-almost-free/"/>
        <id>https://bec-systems.com/149/nand-flash-is-almost-free/</id>
        
        <content type="html" xml:base="https://bec-systems.com/149/nand-flash-is-almost-free/">&lt;p&gt;&lt;em&gt;original article p&lt;&#x2F;em&gt;ublished in March, 2007&lt;&#x2F;p&gt;
&lt;p&gt;EETimes recently ran an article titled “Plummeting prices make NAND appear almost free” (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.eetimes.com&#x2F;news&#x2F;latest&#x2F;showArticle.jhtml?articleID=197002923&quot;&gt;http:&#x2F;&#x2F;www.eetimes.com&#x2F;news&#x2F;latest&#x2F;showArticle.jhtml?articleID=197002923&lt;&#x2F;a&gt;).  1GBytes parts cost around $55 in Nov 2005. As of 2007-03-28, a 1GBytes part costs around $8.  This is almost an order of magnitude reduction in a little over a year.  This article examines the impact this price drop will have on embedded systems and the changes we will likely see including: storage is now at post-scarcity, will “embedded” distributions become obsolete, will uclibc become obsolete, and challenges with large NAND flash parts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-major-components-in-an-embedded-computer&quot;&gt;3 major components in an embedded computer&lt;&#x2F;h3&gt;
&lt;p&gt;The 3 major components in an embedded computer are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;processor&lt;&#x2F;li&gt;
&lt;li&gt;RAM&lt;&#x2F;li&gt;
&lt;li&gt;Flash Storage&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All of these components have been gradually decreasing in price over the years, and there has been a corresponding gradual increase in the use of complex embedded systems.  However, the drop in NAND flash in the last year represents more of a step change, and will likely result in some more drastic changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;we-are-to-the-point-of-post-scarcity-for-flash-storage&quot;&gt;We are to the point of post-scarcity for Flash storage&lt;&#x2F;h3&gt;
&lt;p&gt;Up to this point, most full featured embedded Linux systems contained 16-64MB of NOR flash.  A full featured graphical Linux terminal requires about 20-30MB of flash disk space just for applications and libraries.  So, in the past we were still concerned about application footprint.  The was a lot of incentive to not cross the 32MB to 64MB boundary, etc.  With 1GiB of flash now costing less than $10, we essentially have unlimited flash storage in the context of an embedded Linux distribution.  We will probably see the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;faster time to market as we need to spend less time optimizing&lt;&#x2F;li&gt;
&lt;li&gt;increased use of GTK+ as the standard GUI toolkit.  We no longer care how much space GTK+ takes.&lt;&#x2F;li&gt;
&lt;li&gt;more debugging features can be left in the production system.  Why not leave VIM, Minicom, and SSH in the build if we have plenty of space.  These non-critical features will lower the cost of maintaining a product.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;will-embedded-distributions-become-obsolete&quot;&gt;Will “embedded” distributions become obsolete?&lt;&#x2F;h3&gt;
&lt;p&gt;There has always been a great deal of interest in running Debian and other “standard” distributions in embedded systems.  With 1GiB of storage, this is going to be a lot more practical.  However, with a little experience, you soon realize that distribution size is only one of the many factors.  Another equally important factor is the ability to easily automate the build process for the entire project, including custom applications and image generation for programming.  With complex systems like Linux, it is easy to get into the hack-n-slash mode where it takes a lot of manual steps to build the system.  While this may seem OK when you building the system, it ends up causing a lot of pain and errors once you get in a hurry, of down the road when you are trying to maintain the system.  Ability to easily customize the distribution is another requirement.  OpenEmbedded (http:&#x2F;&#x2F;openembedded.org), and other build systems provide these features.  I think we will see a big increase in Debian and other standard Linux distributions in Embedded systems, but OpenEmbedded and other embedded build systems will continue to grow in use as well because there are many factors in the equation.  This is the nice thing about open source – use what works best for you.&lt;&#x2F;p&gt;
&lt;p&gt;Building and maintaining an embedded system is a lot different than setting up and maintaining a desktop or server system.  Other articles related to this topic include: &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&lt;&#x2F;a&gt; and &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;will-uclibc-become-obsolete&quot;&gt;Will uclibc become obsolete?&lt;&#x2F;h3&gt;
&lt;p&gt;Because flash is now cheap, why do we need to use uclibc (small footprint libc) – can’t we just use glibc.  For full featured embedded Linux systems, this argument makes sense.  However, there is push toward higher integration at the low end.  Many companies are offering 32-bit “microcontrollers” with integrated flash and RAM.  The processors in these devices are more than capable of running Linux.  The limitation to date has been the RAM and Flash size.  The available memory in 32-bit microcontrollers will increase over time enabling them to run a low end uclibc based system.  The idea of running Linux on a system that is composed of a single chip is very interesting.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;challenges-with-large-nand-flash-parts&quot;&gt;Challenges with large NAND flash parts&lt;&#x2F;h3&gt;
&lt;p&gt;What challenges will using large NAND parts present?  In general, dealing with NAND is a lot more complex than with NOR flash.  For reading, NOR parts present a simple memory mapped interface.  A NAND interface is not memory mapped and looks more like a FIFO or a Hard Drive interface.  This makes booting from NAND flash much more difficult.  Some parts present a memory mapped interface for an initial loader.  Some processors build NAND flash bootloading into the processor.  Other systems boot from a small NOR flash and use NAND after the system has booted.&lt;&#x2F;p&gt;
&lt;p&gt;Filesystems are also a challenge with NAND flash.  The standard method is to use JFFS2 which was designed for smaller NOR parts.  JFFS2 works well, but is a log based filesystem.  This means it has to scan the entire file system on mount and store the entire inode chain in memory.  This takes lots of time and uses lots of RAM.  For small devices (64MB), this is tolerable, but for large devices the mount time can take 10’s of seconds.   YAFFS2 is another log based flash filesystem designed specifically for NAND flash which includes a feature called checkpointing that bypasses the normal mount scanning.  Another development is LogFS which looks promising, but will probably not be ready until mid&#x2F;late 2007.&lt;&#x2F;p&gt;
&lt;p&gt;Programming NAND flash can also be a challenge.  Because NAND flash can contain bad blocks, programming is a lot more complex.  Traditionally, flash programming in a NOR system was done by the bootloader.  For a system that boots from NOR flash, programming the NAND flash can be done from a small Linux system (see &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;66&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;66&#x2F;9&#x2F;&lt;&#x2F;a&gt;).  If you are booting from NAND flash, programming may be done with a JTAG programmer that supports NAND flash, or by downloading a small bit of bootstrap code into the processors internal memory using JTAG, and this bootstrap code then has enough functionality to program the NAND flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The lower NAND prices will bring about change in the way embedded systems are built.  Please comment if you have addtional ideas or observations.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Do you need &quot;software update&quot; functionality in your Embedded Linux system?</title>
        <published>2007-02-21T00:00:00+00:00</published>
        <updated>2007-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/146/do-you-need-software-update/"/>
        <id>https://bec-systems.com/146/do-you-need-software-update/</id>
        
        <content type="html" xml:base="https://bec-systems.com/146/do-you-need-software-update/">&lt;p&gt;In this day and age, most embedded systems include a way for users to easily update software once the device has been deployed.  This article discusses the requirements for a field update mechanism along with pointers for how to implement.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;update-mechanism-requirements&quot;&gt;Update Mechanism Requirements&lt;&#x2F;h3&gt;
&lt;p&gt;Requirements for a field update mechanism might be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;easy for users to perform updates.&lt;&#x2F;li&gt;
&lt;li&gt;little chance of “bricking” a unit if reset occurs during update.&lt;&#x2F;li&gt;
&lt;li&gt;ability to update all of the software in the unit&lt;&#x2F;li&gt;
&lt;li&gt;in this case, update from files on a USB Storage device&lt;&#x2F;li&gt;
&lt;li&gt;ability to program NOR and NAND flash&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Other systems may have requirements to update from a network, Compact Flash card, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-usb-wrinkle&quot;&gt;The USB wrinkle&lt;&#x2F;h3&gt;
&lt;p&gt;System update is typically done by the bootloader.  In this case, we are using a Compulab cm-x270 module (&lt;a href=&quot;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&quot;&gt;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&lt;&#x2F;a&gt;) that has a proprietary boot loader and does not support updates from a USB storage device.  Therefore, we need to run the updates from the context of the Linux operating system which has drivers for USB and the NAND flash.  We decided that the best way in this case is to have a small Linux OS image that contains enough functionality to update the main filesystem.  This also provides us with the capability to recover if the main filesystem ever gets corrupted.  The flash layout for the system is:&lt;&#x2F;p&gt;
&lt;table border=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt; Partition&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;Flash Device&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;Size&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;File System&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt; Description&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel&lt;&#x2F;td&gt;
&lt;td&gt;NOR&lt;&#x2F;td&gt;
&lt;td&gt;1536KiB&lt;&#x2F;td&gt;
&lt;td&gt;NA&lt;&#x2F;td&gt;
&lt;td&gt;Linux kernel&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Update rootfs&lt;&#x2F;td&gt;
&lt;td&gt;NOR&lt;&#x2F;td&gt;
&lt;td&gt;2304KiB&lt;&#x2F;td&gt;
&lt;td&gt;Initramfs (RO)&lt;&#x2F;td&gt;
&lt;td&gt;Small rootfs that contains just enough functionality to update the system&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Main rootfs&lt;&#x2F;td&gt;
&lt;td&gt;NAND&lt;&#x2F;td&gt;
&lt;td&gt;512MiB&lt;&#x2F;td&gt;
&lt;td&gt;JFFS2 (RW)&lt;&#x2F;td&gt;
&lt;td&gt;Main rootfs including application&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;There are other schemes that could work as well.  One way might be to have two identical application partitions and only update one at a time.  A reset while updating the kernel or the update rootfs does have the potential of “bricking” the system, but most of the updates will be for the Main rootfs, so we think this risk is low enough to be acceptable in this system.  The update rootfs is loaded into RAM before it is used, so there is little chance of it being corrupted during normal operation.  Running the update rootfs from ram is also convenient in that we can easily re-program the update rootfs in flash as we are not directly mounting the filesystem in flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;building-the-update-rootfs&quot;&gt;Building the Update rootfs&lt;&#x2F;h3&gt;
&lt;p&gt;The base update rootfs is built with OpenEmbedded as described in &lt;a href=&quot;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&quot;&gt;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&lt;&#x2F;a&gt;.  Once we had the system booting into the update rootfs, we had to add the following functionality:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Boot the main rootfs from NAND flash&lt;&#x2F;li&gt;
&lt;li&gt;look for update files on a USB Storage device and flash the kernel, update rootfs, and main rootfs as needed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Booting the NAND flash image is accomplished using the busybox &lt;em&gt;switch_root&lt;&#x2F;em&gt; application.  This utility allows you to easily switch to another rootfs from an initramfs.  There are a few gotchas to be aware of when working with switch_root:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;switch_root must be “exec’d” from the init process with PID=“1”.&lt;&#x2F;li&gt;
&lt;li&gt;switch_root requires a “&#x2F;init” file to be present&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above functionality was accomplished by writing a shell script called &#x2F;init.  If an error occurs, the &#x2F;init shell script then launches the standard init process in &#x2F;sbin&#x2F;init which provides a terminal and allows for easy debugging.  The mtd-utils package provides a handy utility called &lt;em&gt;nandwrite&lt;&#x2F;em&gt; which can be used to write jffs2 images to NAND flash (handles bad blocks, etc).  At some point, we may remove all the extra functionality from the update rootfs like the standard sysvinit, terminal login, etc, but for now it is handy to have for debugging.  To give you an idea how easy it is to write to flash from a shell script, consider the following snippets:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# write Image into update rootfs parition
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;cat &#x2F;usb&#x2F;nor_rootfs.img &amp;gt; &#x2F;dev&#x2F;mtd2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;# write Image to NAND rootfs partition
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;flash_eraseall &#x2F;dev&#x2F;mtd3
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;nandwrite &#x2F;dev&#x2F;mtd3 &#x2F;usb&#x2F;nand_jffs2.img
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;# and to launch rootfs in nand flash
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;exec switch_root -c &#x2F;dev&#x2F;console &#x2F;jffs2 &#x2F;sbin&#x2F;init 5
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Having typically used bootloaders for system update in the past, I’m very pleased with how this mechanism worked out.  Thanks to the flexibility of Linux and OpenEmbedded, this only took several days to implement and debug.  Writing update programs with shell scripts at the application level gives you a lot of flexibility and allows you to use standard Linux drivers for USB and Flash access which are very robust.  At some point if there is interest, we may look at cleaning up our code and contributing functionality to OpenEmbedded to generate a more generic update initramfs.  Please contact us or leave a comment if you are interested in collaborating on something like this.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a tiny &quot;safe&quot; boot image using OpenEmbedded</title>
        <published>2007-02-16T00:00:00+00:00</published>
        <updated>2007-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/143/building-a-tiny-safe-boot-image-using-openembedded/"/>
        <id>https://bec-systems.com/143/building-a-tiny-safe-boot-image-using-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/143/building-a-tiny-safe-boot-image-using-openembedded/">&lt;p&gt;We are currently working a project that contains cm-x270 module (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&lt;&#x2F;a&gt; ) which contains 4MB of NOR flash and 128MB of NAND flash.  The Linux kernel and a small root file system (rootfs) will be stored in NOR flash, and the main rootfs in the NAND flash.  The rootfs in the NOR flash will be used to update the system from a USB Flash drive in the field.  This article describes how to build a small boot rootfs using OpenEmbedded.  We also look at various ways to store the image in flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirments&quot;&gt;Requirments&lt;&#x2F;h3&gt;
&lt;p&gt;In many embedded systems, field upgrades is a requirement.  There are many ways to organize this, but one of the most reliable is to have two rootfs partitions.  The first partition is a “safe” rootfs that is only used to update the second partition.  The second partition contains the main application and can be updated in the field.  If a programming error, or power loss occurs while updating the 2nd partition,  you can always boot into the first rootfs partition and restart the process.&lt;&#x2F;p&gt;
&lt;p&gt;The kernel and the bootloader in this system take up about 1.5MB (out of 4MB total) of the NOR flash.  This leaves us with about 2.5MB for the update rootfs.  Because we are building the rest of the system using OpenEmbedded (OE), it may make sense for us to also build this update rootfs using OE to keep everything in one build environment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uclibc-glibc-or-klibc&quot;&gt;uclibc, glibc, or klibc?&lt;&#x2F;h3&gt;
&lt;p&gt;There are several libc libraries that are commonly used to build Embedded Linux systems.  glibc is the standard that is used in desktop and sever systems and is what is being used in the main NAND rootfs partition.   uclibc is smaller than glibc is often used in space constrained systems.  klibc is a very minimal libc subset that supports operations typically used in an initramfs.  Because we are already using glibc, we decided to try this first as we could then use the same toolchain and build tree and just generate two images – one for NAND, and one for NOR.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openembedded-support-for-small-images&quot;&gt;OpenEmbedded support for small images&lt;&#x2F;h3&gt;
&lt;p&gt;OE includes a &lt;strong&gt;task-base-minimal&lt;&#x2F;strong&gt; meta target that can be used as a basis for a small images, or you can create your own based on task-base.  You will then need to create a custom image recipe that will use this meta task.  An example is shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;PR = &amp;quot;r0&amp;quot;

export IMAGE_BASENAME = &amp;quot;svs_nor&amp;quot;
export PACKAGE_INSTALL = &amp;quot;task-min&amp;quot;
# keep extra language files from being installed
export IMAGE_LINGUAS = &amp;quot;&amp;quot;

RDEPENDS = &amp;quot;task-min&amp;quot;

IMAGE_FSTYPES = &amp;quot;tar jffs2 ext2 cramfs squashfs squashfs-lzma cpio.gz&amp;quot;
IMAGE_ROOTFS_SIZE_ext2=&amp;quot;10240&amp;quot;

#EXTRA_IMAGECMD_jffs2=&amp;quot;--pad=0x1000000 --eraseblock=0x40000&amp;quot;
EXTRA_IMAGECMD_jffs2=&amp;quot;&amp;quot;

inherit image
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, I had defined a custom recipe for task-min based on task-base, which installs the following packages:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@compulab-pxa270:~$ ipkg list_installed
base-files - 3.0.14-r58 -
base-passwd - 3.5.9-r2 -
busybox - 1.2.1-r11 -
initscripts - 1.0-r86 -
ipkg - 0.99.163-r1 -
ipkg-collateral - 1.0-r5 -
libc6 - 2.5-r4 -
libgcc1 - 4.1.1-r10 -
libipkg0 - 0.99.163-r1 -
makedevs - 1.0.0-r2 -
sysvinit - 2.86-r32 -
sysvinit-inittab - 2.86-r32 -
sysvinit-pidof - 2.86-r32 -
task-min - 1.0-r1 -
tinylogin - 1.4-r3 -
update-rc.d - 0.7-r0 -
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;storing-the-nor-filesystem-in-flash&quot;&gt;Storing the NOR filesystem in flash&lt;&#x2F;h3&gt;
&lt;p&gt;OE can generate images for many different flash filesystems and initrd mechanisms.  These are specified in the &lt;strong&gt;IMAGE_FSTYPES&lt;&#x2F;strong&gt; variable in the above recipe.  In this case, I chose to generate many different filesystems so I could see evaluate how much compression I would get with each filesystem type.  The results:&lt;&#x2F;p&gt;
&lt;table style=&quot;height: 173px;&quot; border=&quot;0&quot; width=&quot;232&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rootfs Type&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;Size (bytes)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;squashfs-lzma&lt;&#x2F;td&gt;
&lt;td&gt;1785856&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;tar.bz2&lt;&#x2F;td&gt;
&lt;td&gt;1918243&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;cpio.gz&lt;&#x2F;td&gt;
&lt;td&gt;2024558&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;squashfs&lt;&#x2F;td&gt;
&lt;td&gt;2109440&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;cramfs&lt;&#x2F;td&gt;
&lt;td&gt;2265088&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;jffs2&lt;&#x2F;td&gt;
&lt;td&gt;2455396&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;ext2 (uncompressed)&lt;&#x2F;td&gt;
&lt;td&gt;5481000&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;I ended up choosing the cpio.gz format as it can be loaded directly into an initramfs filesystem by the kernel.   There are several advantages to using an initramfs for this task:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You don’t have to mess around setting up tmpfs filesystems for directories that need to be writable.&lt;&#x2F;li&gt;
&lt;li&gt;You can update the NOR flash partition while you are running out of the initramfs filesystem.&lt;&#x2F;li&gt;
&lt;li&gt;It is fairly small with only squashfs-lzma being smaller.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;future-optimizations&quot;&gt;Future Optimizations&lt;&#x2F;h3&gt;
&lt;p&gt;For now, the glibc based solution is &lt;em&gt;good enough&lt;&#x2F;em&gt; because it fits in the flash space we have and it is easy to build with our existing build environment.  In the future, we may move to a uclibc or klibc based solution and try to reduce our flash size (OpenEmbedded supports both klibc and uclibc).  The above image sizes can also be reduced by removing ipkg and other components that are not needed.&lt;&#x2F;p&gt;
&lt;p&gt;This exercise illustrates many of the advantages of Linux and OpenEmbedded.  With very little work, I can produce exactly what I need.  The ability of the 2.6 Linux kernel to load a cpio archive into an initramfs is a very elegant solution for small boot images.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 PXA270 module review</title>
        <published>2007-01-30T00:00:00+00:00</published>
        <updated>2007-01-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/77/compulab-cm-x270-pxa270-module-review/"/>
        <id>https://bec-systems.com/77/compulab-cm-x270-pxa270-module-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/77/compulab-cm-x270-pxa270-module-review/">&lt;p&gt;We are in the process of supporting a customer who is designing a product that uses the Compulab cm-x270 “Computer-on-module”.  The cm-x270 is a small computer module 66x44x7mm that contains an Intel PXA270 ARM processor similar to those found in many PDAs or smart phones.  This review provides an overview of the cm-x270, why it was selected, and how we are using it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;project-needs&quot;&gt;Project Needs&lt;&#x2F;h3&gt;
&lt;p&gt;For this project, we needed a low cost embedded computer that could drive a VGA (640x480) color display.  The graphical user interface for the device was fairly advanced, so we were also looking at a system that could run a modern OS with an advanced graphical toolkit.  After discussing the display requirements with the customer, we concluded that we needed a 32-bit processor with a LCD display controller.  As there was some custom circuitry needed, a configuration where the customer could design a custom baseboard and use an off-the-shelf computer module seemed optimal.  The schedule was also very aggressive and we did not have the time or budget to develop a full custom processor board.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cm-x270&quot;&gt;CM-X270&lt;&#x2F;h3&gt;
&lt;p&gt;After researching a number of computer modules, we chose the cm-x270 from Compulab.  The cm-x270 is a module that includes the following components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Intel PXA270 ARM processor (up to 520Mhz)&lt;&#x2F;li&gt;
&lt;li&gt;802.11b Interface&lt;&#x2F;li&gt;
&lt;li&gt;up to 128MB SDRAM&lt;&#x2F;li&gt;
&lt;li&gt;128-512MB NAND flash&lt;&#x2F;li&gt;
&lt;li&gt;up to 4MB NOR flash&lt;&#x2F;li&gt;
&lt;li&gt;PCMCIA&lt;&#x2F;li&gt;
&lt;li&gt;PCI&lt;&#x2F;li&gt;
&lt;li&gt;Serial Ports&lt;&#x2F;li&gt;
&lt;li&gt;Touch panel controller (UCB1400)&lt;&#x2F;li&gt;
&lt;li&gt;Host and Slave USB&lt;&#x2F;li&gt;
&lt;li&gt;and other features …&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For more details visit the compulab web site (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;http&#x2F;&#x2F;www.compulab.co.il&quot;&gt;http:&#x2F;&#x2F;http:&#x2F;&#x2F;www.compulab.co.il&lt;&#x2F;a&gt; ).  The cm-x270 provides a very impressive number of features in a very small space.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a picture of the cm-x270 mounted on the Compulab SBC-X270 baseboard with a VGA display.  The system is running the GPE Palmtop Environment built with OpenEmbedded.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;cm-x270-002-1.jpg&quot; alt=&quot;cm-x270-002&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;low-cost&quot;&gt;Low Cost&lt;&#x2F;h3&gt;
&lt;p&gt;Perhaps the most impressive feature of the cm-x270 is the cost.  When ordering in volume, Compulab will build the module with only the components you need.  For prototyping, you can order a standard offering with all components populated.  Starting a price of $50, it is the lowest cost module we found.  The configuration we will be using costs around $98 in 2K quantities (64MB DRAM, 4MB NOR Flash, 512MHz + 128MB NAND Flash + Audio&#x2F;Touchscreen + RTC).  Eventually, we may be able to reduce some of the features and get the price down around $70 per module.&lt;&#x2F;p&gt;
&lt;p&gt;At this price, the cm-x270 provides a very cost effective way to develop a low volume product (a few thousand per year) with advanced features provided by the PXA270 processor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;documentation&quot;&gt;Documentation&lt;&#x2F;h3&gt;
&lt;p&gt;The bootloader and hardware design of the cm-x270 is proprietary.  Compulab does not supply schematics for the design or source code to the bootloader.  The documentation provided is adequate and provided all the information we needed to complete the design.  Compulab also provides schematics for their development baseboard, which is helpful.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bootloader&quot;&gt;Bootloader&lt;&#x2F;h3&gt;
&lt;p&gt;The cm-x270 bootloader provides typical features found in an embedded processor bootloader, including: a serial console, NAND and NOR flash programming, download images from a tftp server, downloading images over a USB connection to a PC, and a number of other configuration commands.  The tftp download works very well and is fast.  The USB download is much slower, but is convenient for systems that do not have a network connection.  The USB download requires a windows PC with a specific version of Microsoft ActiveSync installed, which is unfortunate.  A more general solution that uses something like libusb (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;libusb.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;libusb.sourceforge.net&#x2F;&lt;&#x2F;a&gt;) instead of ActiveSync would be preferred as it could then run on both Windows and Linux computers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-support&quot;&gt;Linux Support&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides a fairly complete port of the 2.6.16 Linux kernel for the cm-x270 in the form of a kernel patch.  Most of the peripherals we tested seem to work with the following exceptions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The SD card driver is not preempt safe.  In this application, we need kernel preemption turned on to meet certain real-time requirements.&lt;&#x2F;li&gt;
&lt;li&gt;The Touch driver contains a small bug that does not allow applications using it to exit properly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Overall, support is pretty good and enabled us to get started with development quickly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nand-flash-driver&quot;&gt;NAND Flash Driver&lt;&#x2F;h3&gt;
&lt;p&gt;As the Compulab module only provides 4MB of NOR flash, using the NAND flash is a requirement when implementing a full featured Linux system with an advanced graphical user interface.  Compulab provides a binary module that is linked into a kernel driver to support the NAND flash.  This driver provides a block interface on which standard filesystems like ext2 can be used.  The NAND driver has worked fairly well, although we have seen several cases where we get I&#x2F;O errors if we remove power to the device without shutting down the system properly.  The way to recover is to do a low level format the NAND flash.  This should not be an issue with this product as we will have a backup battery that will be used to power the system during shutdown if power is removed.  We may eventually move to an open source JFFS2 flash driver as time permits.&lt;&#x2F;p&gt;
&lt;p&gt;The proprietary NAND driver presents an additional wrinkle in that the driver cannot be linked into the kernel due to GPL licensing requirements.  One solution is to boot a small root file system from NOR flash that includes the NAND driver module, and then proceed to boot from NAND flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gnu-linux-root-file-system&quot;&gt;GNU&#x2F;Linux Root File System&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides an example root file system (I think based on Debian) and suggests using scratchbox to build applications.  We looked at it briefly, but then decided to build our own rootfs using OpenEmbedded for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We can easily add additional packages from the extensive OpenEmbedded catalog as needed.&lt;&#x2F;li&gt;
&lt;li&gt;Allows us to have an rootfs independent of the module – we can more easily move to other processor modules or architectures in the future.&lt;&#x2F;li&gt;
&lt;li&gt;OpenEmbedded provides us with mechanisms for package management and building complete images that include our applications and tweaks to the OS.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For more information on OpenEmbedded, read our “&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&quot;&gt;Introduction to OpenEmbedded&lt;&#x2F;a&gt; “.  With OpenEmbedded, we were able to quickly build a toolchain and a root file system that included the kdrive version of Xwindows and GTK+ libraries.  This rootfs fits in less than 32MB of flash disk space, which is much smaller than Compulab’s OS image.&lt;&#x2F;p&gt;
&lt;p&gt;We have also added machine configuration files to the OpenEmbedded project to support the cm-x270: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;repo&#x2F;org.openembedded.dev&#x2F;conf&#x2F;machine&#x2F;compulab-pxa270.conf&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;repo&#x2F;org.openembedded.dev&#x2F;conf&#x2F;machine&#x2F;compulab-pxa270.conf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-support&quot;&gt;Design Support&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab seems mainly interested in customers who are interested in purchasing modules in volume.  They do not sell low cost development boards such as LogicPD’s $500 board.  Compulab requires you to purchase a fairly high cost development system ($1900) in order to get started.  Part of this cost is to pay for Compulab’s support costs.  For companies who do not have experience designing systems with PXA270 class processors, we highly recommend getting some up-front help from someone who has experience with these systems.  Even though the module takes care of a lot of the design complexity, it helps to have a detailed understanding of the PXA270 and associated components, as you still need to interact with them.  Consulting companies like BEC Systems can provide assistance in the form of hardware design reviews and Linux OS support to accelerate projects and help avoid costly mistakes and delays.  As Compulab designs only the module, there is only so much they can do when you run into problems – as shown in the next section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;issues-encountered&quot;&gt;Issues Encountered&lt;&#x2F;h3&gt;
&lt;p&gt;Overall, the project using the cm-x270 has gone well.  The only real challenge we have faced is a latch-up issue with the ITE PCI controller on the cm-x270 module.  It appears that this part is very sensitive to the characteristics of the 3.3V supply to the module.  After a considerable amount of debugging and testing, we were able to solve this problem with some filtering and slowing down the rise time of the 3.3V supply.  This is a good example of where a project can get difficult very quickly when things don’t work as expected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;So far, the cm-x270 has worked very well in this project.  With its low cost, it is a very attractive option for companies wanting to implement advanced functionality in their products, but don’t have the time, sales volumes, or experience to justify a full processor board design.  Feel free to post comments about your experiences using embedded computer modules.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction to OpenEmbedded part 1</title>
        <published>2007-01-12T00:00:00+00:00</published>
        <updated>2007-01-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/141/introduction-to-openembedded-part-1/"/>
        <id>https://bec-systems.com/141/introduction-to-openembedded-part-1/</id>
        
        <content type="html" xml:base="https://bec-systems.com/141/introduction-to-openembedded-part-1/">&lt;p&gt;This is the first in a multi-part series on the OpenEmbedded development environment.  This and subsequent articles will provide an introduction to OpenEmbedded, why to use it,  how it works, and will provide examples of how BEC has used OE in various projects.&lt;&#x2F;p&gt;
&lt;p&gt;Part 1 – Why do we need OpenEmbedded?  This article discusses some of the problems developers face when building embedded Linux systems, such as collecting the pieces needed, setting up a repeatable build environment, cross-compiling, customizing a system, and licensing issues.  Future articles will cover how OE addresses some of these issues.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;embedded-linux-complex-system&quot;&gt;Embedded Linux = Complex System&lt;&#x2F;h3&gt;
&lt;p&gt;The fundamental problem with building Embedded Linux systems is the sheer complexity.  Lets face it, there is a lot going on in a typical Embedded Linux system.  Millions of lines of code are being compiled.  Typically there are tens to hundreds of applications and libraries that need to be built.  Linux supports many different processor architectures.  The size of Linux leads to the conclusion that a good deal of automation is required to manage all this.  In my paper “Tips for Planning your Embedded Linux Project” (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt; ), the analogy of the Iceberg is presented.  The application specific software in the project is the part of the Iceberg that is above water – the part you see.  Most of the system (Linux and system applications) is below water – you don’t see it.   The part under water is the big unknown and has the potential to add a lot of variance to a project.  Note: this problem is not specific to Linux – any system of this complexity that is targeted to so many different applications faces the same problem.  As a side, one might ask why use Linux if it is so complex?  The answer is simple – features.  Linux has the features and device support required for many Embedded products to be competitive.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collecting-and-building-all-the-pieces&quot;&gt;Collecting and building all the pieces&lt;&#x2F;h3&gt;
&lt;p&gt;There are a lot of pieces of software that need to come together to build an Embedded Linux system.  This may include a toolchain, kernel, system libraries, and many system applications and configuration scripts required to make a system work.  The is not something you want to do manually, or building an embedded Linux system quickly becomes impractical for most developers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;repeatable-builds&quot;&gt;Repeatable Builds&lt;&#x2F;h3&gt;
&lt;p&gt;With any software project, it is highly desirable to have a build system that is easily repeatable – which means it can be reproduced at any time on a wide variety of development workstations.  Some of the of the situations I have run into that are less than desirable are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Being dependent on a vendor to provide a pre-compiled root file system image for a system.  What happens when you need to add something two years down the road (such as foreign language support) and you don’t have a build system where you can easily reproduce the current build?&lt;&#x2F;li&gt;
&lt;li&gt;Being dependent on a golden build machine that takes a lot of work to set up and is very difficult to reproduce.  If you have a build environment where all the developers use one machine to build software, you may want to investigate if you are in this situation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What is really needed is a build system where you can check the build system out of a source control system onto about any Linux workstation at any point in time, type make, and a few hours later you have an image.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gpl-compliance&quot;&gt;GPL Compliance&lt;&#x2F;h3&gt;
&lt;p&gt;If you distribute binaries in your product compiled from GPL software, you must offer to provide the source code for these binaries.   Do you have easy access to the source for everything that is in your product?  Do you even know what all is in your product?  It is not good enough to simply point to someone else’s distribution or web site and say “I use that”.  As the founder of the MEPIS distribution &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;software.newsforge.com&#x2F;article.pl?sid=06&#x2F;06&#x2F;23&#x2F;1728205&amp;amp;tid=150&quot;&gt;discovered&lt;&#x2F;a&gt;, the GPL license explicitly states the distributor of the GPL code is obligated to provide source code for up to 3 years.  So if you build a distribution by copying binaries from a pre-build distribution, you may have a problem.  In one case I am familiar with, a company was in the last stages of a multi-year product development cycle.  They then discovered that they did not have the source code used to build the GPL binaries in the system.  The company that built the distribution for them was out of business and the open source project the binaries where originally obtained from no longer maintained the sources.  Although it may be possible to find all of the old sources, it is a huge amount of work and would probably be easier to just start over and build new distribution.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;customizing-the-system&quot;&gt;Customizing the system&lt;&#x2F;h3&gt;
&lt;p&gt;For most embedded systems, the distribution needs to be customized.  There are often requirements such as custom software update schemes.  Ideally, a good build system should easily allow you to integrate changes into the build system in a automated way, so that you don’t have any manual steps in the process of creating an image for the embedded system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cross-compiling&quot;&gt;Cross Compiling&lt;&#x2F;h3&gt;
&lt;p&gt;The above “repeatable build” requirement that you be able to build an image for your embedded target on about any Linux workstation leads to a requirement for cross-compiling.  Cross-compiling is the process of creating executable code for a platform different than the one on which the cross compiler is run (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cross_compiler&quot;&gt;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cross_compiler&lt;&#x2F;a&gt;).  Cross compiling many standard open source applications and libraries can be difficult on a good day, and near impossible on a bad day, as many of them were not written with cross compiling in mind.  Therefore, a good build environment should have tools that automate the process of cross-compiling as well as provide the ability to easily cross compile the many common programs and libraries that may be needed in an embedded Linux system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;As we examine some of the challenges, it should be obvious that putting together a production embedded Linux system is not something to be done in an ad-hoc fashion.  There are several ways to approach this problem.  Stay tuned for future articles where we explore how the OpenEmbedded build system solves these problems (subscribing to our blog or newsletter is a good way to do this).&lt;&#x2F;p&gt;
&lt;p&gt;Also, please post comments about your experiences – we like to hear and learn from you.  We are also interested in what problems you face when building Embedded systems.  This input will be used when writing future articles.  Thanks!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Remote access for embedded systems behind a firewall</title>
        <published>2006-12-19T00:00:00+00:00</published>
        <updated>2006-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/137/remote-access-for-embedded-systems-behind-a-firewall/"/>
        <id>https://bec-systems.com/137/remote-access-for-embedded-systems-behind-a-firewall/</id>
        
        <content type="html" xml:base="https://bec-systems.com/137/remote-access-for-embedded-systems-behind-a-firewall/">&lt;p&gt;When deploying embedded systems, wouldn’t it be nice if you could easily set up remote access for troubleshooting and updates?  With Embedded Linux systems, this is quite easy to do.  This article will explore how to use SSH to set up remote access to an embedded system behind a firewall without using VPN or special network setup and presents a few tips for making this setup work well.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;With today’s complex embedded systems, testing and deployment can be a challenge.   During the initial testing and roll-out, a new system may need to be carefully monitored to assure it is operating correctly.  Embedded Systems programming is different than application programming in that often you are interfacing with external I&#x2F;O.  The behavior of things external to the embedded system are often very difficult to model during development; therefore time must be spent in the field testing the system in real-world situations.  Being able to remotely access the system during testing is very convenient.&lt;&#x2F;p&gt;
&lt;p&gt;As with most networked computer systems, networked embedded systems are typically deployed on a network behind a firewall. It is very easy to log in and administer any Linux system you have direct network access to – the challenge is getting to a system behind a firewall.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;options-for-remote-access&quot;&gt;Options for remote Access&lt;&#x2F;h3&gt;
&lt;p&gt;There are several general options for remote access to networks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;VPN&lt;&#x2F;li&gt;
&lt;li&gt;Port forwarding at the firewall&lt;&#x2F;li&gt;
&lt;li&gt;PC remote access technologies.  These are typically single session type connections that are initiated by the PC user.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The disadvantage of the above technologies is they require involvement from the IT department or users of the remote network.  BEC is currently involved in the deployment of a system that uses embedded computers in six different buildings.  Each building has its own firewalled network.  Getting remote access to all of these networks is a big task and everyone is busy.  An ideal solution would be a way to communicate directly with each embedded computer from a central location, which brings us to SSH …&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ssh&quot;&gt;SSH&lt;&#x2F;h3&gt;
&lt;p&gt;SSH (Secure Shell) is a set of standards and an associated network protocol that is used to establish a secure channel between a local and remote computer.  SSH encrypts all traffic (including passwords) and is generally considered to be very secure if used properly.  Some uses for SSH are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;remote terminal access.&lt;&#x2F;li&gt;
&lt;li&gt;transfer files between computers.&lt;&#x2F;li&gt;
&lt;li&gt;tunnelling and port forwarding between computers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The fact that SSH can be used to forward ports over an encrypted tunnel is what makes remote access possible using what is called a &lt;strong&gt;Reverse SSH&lt;&#x2F;strong&gt; tunnel.  Because the embedded system is behind a firewall with no direct access from the Internet, the connection must be initiated from the embedded system.   A reverse SSH tunnel is set up as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the embedded systems make a SSH connection to an external server that is internet accessible.&lt;&#x2F;li&gt;
&lt;li&gt;The SSH connection is set up so that a port on the external server (let’s pick 2900) is forwarded back over the SSH tunnel to port 22 (port used for SSH) on the embedded system.&lt;&#x2F;li&gt;
&lt;li&gt;The developer connects to 2900 on the external server using SSH.  Because port 2900 on the external server gets forwarded over the SSH tunnel to port 22 of the embedded system, the developer is actually logging into the embedded system.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This connection is illustrated in the figure below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;reverse_ssh_diagram-1.png&quot; alt=&quot;reverse_ssh_diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the above figure, the external server is typically a system located in the developer’s office with only port 22 exposed to the Internet.  Port 2900 is only accessible to developers on the same private network as the server.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;security&quot;&gt;Security&lt;&#x2F;h3&gt;
&lt;p&gt;When talking about any type of remote access technology involving the internet, it is important to consider the security implications.  The reverse SSH mechanism is fairly secure, as everything is encrypted.  SSH is widely used for remote access to servers; therefore it receives a lot of testing and scrutiny.  With the reverse SSH remote access setup, the most likely attack is probably to compromise the external server and then try to access the remote network the embedded system is located on through the embedded system.    If the external server is properly secured, then this mechanism should be fairly safe.  One of the advantages of this scheme is that the embedded system is not directly exposed to the Internet, therefore  securing the embedded system itself is not all that important.&lt;&#x2F;p&gt;
&lt;p&gt;It is obviously very important that the people administering the remote network understand what you are doing – that is where this article can come in handy.  If there are concerns about external developers accessing a network, one mode of operation may be for the the SSH tunnel to be manually started and stopped so that administrators of the remote network know exactly when remote access is enabled.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tips&quot;&gt;TIPS&lt;&#x2F;h3&gt;
&lt;p&gt;A few ideas for making this work well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It may be useful to put the reverse SSH connection in a cron job on the embedded system so that the connection is automatically set up.  If you do this, I advise killing the connection and restarting every so often.  Reverse SSH connections are somewhat fragile and occasionally need restarted if there is a network glitch.&lt;&#x2F;li&gt;
&lt;li&gt;Use the SSH TCPKeepAlive option.  Some firewalls&#x2F;routers will drop a network connection if there is no activity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Using SSH for remote access is another example of the “Big Win” with Embedded Linux – how industrial grade technologies developed for use in server and desktop systems can be readily used in embedded systems (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt; ).  Remote access during the deployment and testing of embedded systems can drastically reduce the amount of time and effort required to roll out an embedded system.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to build GNU&#x2F;Linux for an embedded x86 computer</title>
        <published>2006-11-29T00:00:00+00:00</published>
        <updated>2006-11-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/134/how-to-build-gnulinux-for-an-embedded-x86-computer/"/>
        <id>https://bec-systems.com/134/how-to-build-gnulinux-for-an-embedded-x86-computer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/134/how-to-build-gnulinux-for-an-embedded-x86-computer/">&lt;p&gt;Recently, I had a customer who needed an embedded Linux distribution running on an Advantech PCM-9371 single board computer (SBC).  The PCM-9371 contains a low voltage Celeron or Pentium III processor.  This article describes why the Openembedded build system was chosen and a few tips for running Openembedded on a x86 system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-hard-way&quot;&gt;The hard way!&lt;&#x2F;h2&gt;
&lt;p&gt;There are many ways to put Linux on a x86 embedded system.  There are hundreds of distributions out there and the temptation is always to do something “quick” and just try to trim down one of the standard distributions.  Other shortcuts are often taken, such as compiling your application on a workstation that is running a different distribution and different versions of the libraries used in the embedded systems.  This approach can work, but there are many possible pitfalls:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Several years down the road, it will be difficult to compile applications for your target system as the libraries on the target system are very dated compared to tools and libraries used in standard desktop distributions.  What this means is you will need to keep a “golden” compile machine around for the life of your project – not fun!  I went through an experience like this on a previous version of this same project where it took us a week to set up a build machine to compile applications using a very old version of Debian.&lt;&#x2F;li&gt;
&lt;li&gt;It is difficult to gather GPL sources used to build the distribution you are using.  You are required to supply GPL source code upon request to customers who purchase your product.&lt;&#x2F;li&gt;
&lt;li&gt;To build applications correctly, you really need a build machine that is running the same distribution as the target, unless you set up a cross-compilation or scratchbox environment.&lt;&#x2F;li&gt;
&lt;li&gt;Most distributions are quite large and have difficulty fitting on CF card.&lt;&#x2F;li&gt;
&lt;li&gt;Most distributions are difficult to customize in a clean, systematic way.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;openembedded&quot;&gt;OpenEmbedded&lt;&#x2F;h2&gt;
&lt;p&gt;Considering the disadvantages of using an standard x86 distribution for this project, I chose to use OpenEmbedded (OE).  The OpenEmbedded project (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;openembedded.org&lt;&#x2F;a&gt; ) is a full featured build system for building embedded Linux distributions.  The development is done on a Linux workstation of your choice and the entire distribution is cross-compiled to the architecture of your choice.  The entire build process is automated, including building the toolchain and an image that can be installed on the target embedded system.  Some of the features of OpenEmbedded are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Over 3000 packages that can be built.  About anything you would ever need for an embedded system.&lt;&#x2F;li&gt;
&lt;li&gt;Support for a wide variety of target architectures.  ARM and x86 processors are well supported.&lt;&#x2F;li&gt;
&lt;li&gt;Build system is very self contained.  This means you can do the builds on a variety of different host machines.  Many of the tools OE needs are built by OE, so there is very little dependence on host tools besides a few basics such as Python, make, and other standard tools.  This also means it is much easier to pull the build system out of the archives in several years, load it on a current machine, and do a build.&lt;&#x2F;li&gt;
&lt;li&gt;All source code used in the build is downloaded, so GPL compliance is easy.&lt;&#x2F;li&gt;
&lt;li&gt;and the list goes on …&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;build-and-installation&quot;&gt;Build and Installation&lt;&#x2F;h2&gt;
&lt;p&gt;Setting up an OE build is beyond the scope of this article, but it basically involves selecting a machine and distribution.  In this case, I chose the &lt;em&gt;x86&lt;&#x2F;em&gt; machine and the &lt;em&gt;generic&lt;&#x2F;em&gt; OE distribution.  Several hours later, I had an image in the form of a tar.gz file that I decompressed to a Compact Flash (CF) card.  After installing grub on the CF card, I had a booting Linux distribution that included all the basics (like ssh, ipkg package manager, shell, standard file utilities, etc) in less than 4MB of disk space.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-gtk-and-xwindows&quot;&gt;Adding GTK+ and Xwindows&lt;&#x2F;h2&gt;
&lt;p&gt;This system required support for GTK+ and Xwindows.  To add this involved running the following commands: &lt;em&gt;bitbake xserver-kdrive&lt;&#x2F;em&gt; and &lt;em&gt;bitbake gtk+&lt;&#x2F;em&gt;.  The OE build system then automatically downloaded and compiled the need packages.  The image size is now around 20MB – still fits very easily on a CF card.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-x-running&quot;&gt;Getting X running&lt;&#x2F;h2&gt;
&lt;p&gt;There are several options for running X on a x86 system.  In this case, I chose the quickest way so that my customer could get started with application integration as quickly as possible.  Linux and Xwindows support the standard VESA Framebuffer mode.  Then can be enabled by selecting the CONFIG_FB_VESA kernel config option.  The kdrive version of X can then be started by running Xvesa.  In the future, we may move to an accelerated X driver if needed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;We now have Linux running off of a CF card with full X&#x2F;GTK+ support and the customer can proceed with integration, testing and application development.  Getting to this point took about 1 day of development as we did not encounter any major problems – much less time than it took to resurrect an old build environment used in previous versions of the project.  Future work will involve integrating applications into the OE build system, and customizing the distribution as needed.  Openembedded has proved to be a very valuable tool for getting embedded Linux systems running quickly and maintaining them in a controlled way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Adding software to a Moxa UC7408 using OpenEmbedded</title>
        <published>2006-10-30T00:00:00+00:00</published>
        <updated>2006-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/131/adding-software-to-a-moxa-uc7408-using-openembedded/"/>
        <id>https://bec-systems.com/131/adding-software-to-a-moxa-uc7408-using-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/131/adding-software-to-a-moxa-uc7408-using-openembedded/">&lt;p&gt;One of the big advantages of using Linux in embedded systems is the thousands of applications and drivers available for it (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt; ).  One of the challenges of Embedded Linux is building these applications.  Building applications for an embedded system often involves cross-compiling which is frustrating on a good day.  This article details how to use OpenEmbedded (OE) with the existing toolchain Moxa provides to build a number of applications for the Moxa UC7408.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;web-application-support&quot;&gt;Web Application Support&lt;&#x2F;h2&gt;
&lt;p&gt;My needs for this project were to build a web application that ran on the UC7408 (See &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;55&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;55&#x2F;9&#x2F;&lt;&#x2F;a&gt; for a review of the Moxa UC7408).  The Moxa firmware is fairly full featured and provides php for web application development.  This is probably fine for many applications, but I prefer to build web applications as detailed in this article: &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;46&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;46&#x2F;9&#x2F;&lt;&#x2F;a&gt; .  Because the rest of the application is written in Python, there are advantages to also implementing the web application in Python.  I also wanted to use the sqlite database.  A quick look at the php supplied with the Moxa firmware suggested it was built without sqlite support.  In summary, I needed the following components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Python&lt;&#x2F;li&gt;
&lt;li&gt;Clearsilver&lt;&#x2F;li&gt;
&lt;li&gt;sqlite&lt;&#x2F;li&gt;
&lt;li&gt;minicom&lt;&#x2F;li&gt;
&lt;li&gt;vim&lt;&#x2F;li&gt;
&lt;li&gt;strace&lt;&#x2F;li&gt;
&lt;li&gt;subversion&lt;&#x2F;li&gt;
&lt;li&gt;wget&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above is a fairly small list, but what you don’t see are all the dependencies that also need to be built and installed.  This ends up being many more components.   Some of the items are for development only, but this is Linux – why not have nice tools running on the target system?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;oe-to-the-rescue&quot;&gt;OE to the rescue&lt;&#x2F;h2&gt;
&lt;p&gt;Ideally, the Moxa system would have a complete root file system built with OE running on it.  But I did not have the time or budget to implement this, so I did the next best thing – use the rootfs and toolchain supplied by Moxa along with OE to compile just the applications I needed.  Typically, OE builds the toolchain and Glibc, but fortunately OE provides a very slick way to use an external toolchain and glibc with OE.  How to do this is detailed in the OE manual: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;user-manual&amp;amp;dpage=commonuse_prebuilt_toolchain&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;user-manual&amp;amp;dpage=commonuse_prebuilt_toolchain&lt;&#x2F;a&gt;.  Below is the setup I used:&lt;&#x2F;p&gt;
&lt;p&gt;Environment variables:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;TOOLCHAIN=&#x2F;usr&#x2F;local&#x2F;mxscaleb&#x2F;bin&#x2F;
export PRE_BUILT=&#x2F;usr&#x2F;local&#x2F;mxscaleb&#x2F;armv5b-linux

export CCACHE_DIR=&amp;quot;${TOPDIR}&#x2F;ccache&amp;quot;
export PYTHONPATH=&amp;quot;${TOPDIR}&#x2F;bitbake&#x2F;lib&amp;quot;
export BBPATH=&amp;quot;${TOPDIR}:${TOPDIR}&#x2F;openembedded:${TOPDIR}&#x2F;bitbake&amp;quot;
export PATH=&amp;quot;${TOPDIR}&#x2F;bitbake&#x2F;bin:${TOOLCHAIN}:${PATH}&amp;quot;
export LD_LIBRARY_PATH=
export LANG=C
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Local.conf file:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DL_DIR = &amp;quot;&#x2F;build&#x2F;sva_oe&#x2F;downloads&amp;quot;
BBFILES := &amp;quot;&#x2F;build&#x2F;sva_oe&#x2F;openembedded&#x2F;packages&#x2F;*&#x2F;*.bb&amp;quot;
BBMASK = &amp;quot;&amp;quot;
PREFERRED_PROVIDERS = &amp;quot;virtual&#x2F;qte:qte virtual&#x2F;libqpe:libqpe-opie&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;libsdl:libsdl-qpe&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;${TARGET_PREFIX}gcc-initial:gcc-cross-initial&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;${TARGET_PREFIX}gcc:gcc-cross&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;${TARGET_PREFIX}g++:gcc-cross&amp;quot;
PREFERRED_PROVIDER_virtual&#x2F;libx11 = &amp;quot;diet-x11&amp;quot;
ASSUME_PROVIDED += &amp;quot; virtual&#x2F;${TARGET_PREFIX}gcc &amp;quot;
ASSUME_PROVIDED += &amp;quot; virtual&#x2F;libc &amp;quot;
MACHINE = &amp;quot;moxa&amp;quot;
IPKG_ARCHS = &amp;quot;all arm armv4 armv5te xscale ${MACHINE}&amp;quot;
TARGET_CC_ARCH = &amp;quot;-mcpu=xscale&amp;quot;
TARGET_ARCH = &amp;quot;arm&amp;quot;
PACKAGE_ARCH=&amp;quot;xscale&amp;quot;
TARGET_OS = &amp;quot;linux&amp;quot;
TARGET_FPU = &amp;quot;soft&amp;quot;
DISTRO = &amp;quot;moxa-disro&amp;quot;
DISTRO_NAME = &amp;quot;moxa-distro&amp;quot;
DISTRO_VERSION = &amp;quot;0.0.1&amp;quot;
DISTRO_TYPE = &amp;quot;release&amp;quot;
INHERIT += &amp;quot; package_ipk package_tar debian&amp;quot;
IMAGE_FSTYPES = &amp;quot;jffs2 tar&amp;quot;
PARALLEL_MAKE = &amp;quot;-j 4&amp;quot;
BBINCLUDELOGS = &amp;quot;yes&amp;quot;
CVS_TARBALL_STASH = &amp;quot;http:&#x2F;&#x2F;www.oesources.org&#x2F;source&#x2F;current&#x2F;&amp;quot;
export CC  = &amp;quot;mxscaleb-gcc-3.3.2 ${HOST_CC_ARCH}&amp;quot;
export CXX = &amp;quot;mxscaleb-g++ ${HOST_CC_ARCH}&amp;quot;
export CPP = &amp;quot;mxscaleb-gcc-3.3.2 -E&amp;quot;
export LD = &amp;quot;mxscaleb-ld&amp;quot;
export AR  = &amp;quot;mxscaleb-ar&amp;quot;
export AS  = &amp;quot;mxscaleb-as&amp;quot;
export RANLIB  = &amp;quot;mxscaleb-ranlib&amp;quot;
export STRIP  = &amp;quot;mxscaleb-strip&amp;quot;
TARGET_CPPFLAGS_append = &amp;quot; -I${PRE_BUILT}&#x2F;include &amp;quot;
TARGET_LDFLAGS_prepend = &amp;quot; -L${PRE_BUILT}&#x2F;lib -Wl,-rpath-link, ...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;${PRE_BUILT}&#x2F;lib -Wl,-rpath-link,${PRE_BUILT}&#x2F;qt2&#x2F;lib &amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the above setup, I was able to build the applications I needed with very little effort.  There were a few little problems I ran into, but I was able to quickly work around them.  The result is a number of packages that can be installed on the target system:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bigreqsproto-dev-X11R7.0-1.0.2-r0.tar.gz      python-crypt-2.4.3-ml0.tar.gz
busybox-1.2.1-r1.3.tar.gz                     python-curses-2.4.3-ml1.tar.gz
busybox-udhcpd-1.2.1-r1.3.tar.gz              python-datetime-2.4.3-ml0.tar.gz
clearsilver-0.10.3-r0.tar.gz                  python-db-2.4.3-ml0.tar.gz
clearsilver-dbg-0.10.3-r0.tar.gz              python-devel-2.4.3-ml0.tar.gz
clearsilver-dev-0.10.3-r0.tar.gz              python-distutils-2.4.3-ml0.tar.gz
clearsilver-doc-0.10.3-r0.tar.gz              python-email-2.4.3-ml0.tar.gz
inputproto-dev-X11R7.0-1.3.2-r0.tar.gz        python-fcntl-2.4.3-ml0.tar.gz
ipkg-0.99.163-r1.tar.gz                       python-gdbm-2.4.3-ml0.tar.gz
ipkg-dbg-0.99.163-r1.tar.gz                   python-hotshot-2.4.3-ml0.tar.gz
ipkg-dev-0.99.163-r1.tar.gz                   python-html-2.4.3-ml0.tar.gz
kbproto-dev-X11R7.1-1.0.3-r0.tar.gz           python-idle-2.4.3-ml0.tar.gz
libapr-0-0-0.9.12-r0.tar.gz                   python-image-2.4.3-ml0.tar.gz
libapr-0-bin-0.9.12-r0.tar.gz                 python-io-2.4.3-ml0.tar.gz
libapr-0-dev-0.9.12-r0.tar.gz                 python-lang-2.4.3-ml0.tar.gz
libaprutil-0-0-0.9.12-r0.tar.gz               python-lib-old-and-deprecated-2.4.3-ml0.tar.gz
libaprutil-0-bin-0.9.12-r0.tar.gz             python-logging-2.4.3-ml0.tar.gz
libaprutil-0-dev-0.9.12-r0.tar.gz             python-mailbox-2.4.3-ml0.tar.gz
libcrypto0.9.7-0.9.7g-r1.tar.gz               python-math-2.4.3-ml0.tar.gz
libexpat-bin-2.0.0-r1.tar.gz                  python-mime-2.4.3-ml0.tar.gz
libexpat-dev-2.0.0-r1.tar.gz                  python-mmap-2.4.3-ml0.tar.gz
libexpat-doc-2.0.0-r1.tar.gz                  python-netclient-2.4.3-ml1.tar.gz
libexpat1-2.0.0-r1.tar.gz                     python-netserver-2.4.3-ml0.tar.gz
libgcrypt-dbg-1.2.2-r0.tar.gz                 python-pickle-2.4.3-ml0.tar.gz
libgcrypt-dev-1.2.2-r0.tar.gz                 python-pprint-2.4.3-ml0.tar.gz
libgcrypt-doc-1.2.2-r0.tar.gz                 python-profile-2.4.3-ml0.tar.gz
libgcrypt11-1.2.2-r0.tar.gz                   python-pydoc-2.4.3-ml0.tar.gz
libgdbm-dbg-1.8.3-r2.tar.gz                   python-pyserial-2.2-r1.tar.gz
libgdbm-dev-1.8.3-r2.tar.gz                   python-pysqlite2-2.2.2-ml1.tar.gz
libgdbm-doc-1.8.3-r2.tar.gz                   python-pyxml-0.8.4-ml0.tar.gz
libgdbm3-1.8.3-r2.tar.gz                      python-re-2.4.3-ml0.tar.gz
libgnutls-bin-1.4.0-r1.tar.gz                 python-readline-2.4.3-ml0.tar.gz
libgnutls-dbg-1.4.0-r1.tar.gz                 python-resource-2.4.3-ml0.tar.gz
libgnutls-dev-1.4.0-r1.tar.gz                 python-shell-2.4.3-ml0.tar.gz
libgnutls-doc-1.4.0-r1.tar.gz                 python-stringold-2.4.3-ml0.tar.gz
libgnutls-extra13-1.4.0-r1.tar.gz             python-subprocess-2.4.3-ml0.tar.gz
libgnutls-locale-en+boldquot-1.4.0-r1.tar.gz  python-syslog-2.4.3-ml0.tar.gz
libgnutls-locale-en+quot-1.4.0-r1.tar.gz      python-terminal-2.4.3-ml0.tar.gz
libgnutls-locale-pl-1.4.0-r1.tar.gz           python-tests-2.4.3-ml0.tar.gz
libgnutls-openssl13-1.4.0-r1.tar.gz           python-textutils-2.4.3-ml0.tar.gz
libgnutls13-1.4.0-r1.tar.gz                   python-threading-2.4.3-ml0.tar.gz
libgpg-error-dbg-1.3-r1.tar.gz                python-tkinter-2.4.3-ml0.tar.gz
libgpg-error-dev-1.3-r1.tar.gz                python-unittest-2.4.3-ml0.tar.gz
libgpg-error-locale-de-1.3-r1.tar.gz          python-unixadmin-2.4.3-ml0.tar.gz
libgpg-error-locale-fr-1.3-r1.tar.gz          python-xml-2.4.3-ml0.tar.gz
libgpg-error-locale-pl-1.3-r1.tar.gz          python-xmlrpc-2.4.3-ml0.tar.gz
libgpg-error-locale-ro-1.3-r1.tar.gz          python-zlib-2.4.3-ml1.tar.gz
libgpg-error-locale-vi-1.3-r1.tar.gz          sqlite3-3.3.7-r2.tar.gz
libgpg-error0-1.3-r1.tar.gz                   sqlite3-dbg-3.3.7-r2.tar.gz
libice-dbg-X11R7.1-1.0.1-r0.tar.gz            strace-4.5.14-r3.tar.gz
libice-dev-X11R7.1-1.0.1-r0.tar.gz            strace-dbg-4.5.14-r3.tar.gz
libice6-X11R7.1-1.0.1-r0.tar.gz               strace-doc-4.5.14-r3.tar.gz
libipkg-dev-0.99.163-r1.tar.gz                subversion-1.3.1-r1.tar.gz
libipkg0-0.99.163-r1.tar.gz                   subversion-dbg-1.3.1-r1.tar.gz
liblzo-dbg-1.08-r14.tar.gz                    subversion-dev-1.3.1-r1.tar.gz
liblzo-dev-1.08-r14.tar.gz                    subversion-doc-1.3.1-r1.tar.gz
liblzo1-1.08-r14.tar.gz                       subversion-locale-de-1.3.1-r1.tar.gz
libneon-bin-0.25.5-r0.tar.gz                  subversion-locale-es-1.3.1-r1.tar.gz
libneon-dev-0.25.5-r0.tar.gz                  subversion-locale-fr-1.3.1-r1.tar.gz
libneon-doc-0.25.5-r0.tar.gz                  subversion-locale-it-1.3.1-r1.tar.gz
libneon25-0.25.5-r0.tar.gz                    subversion-locale-ja-1.3.1-r1.tar.gz
libpython2.4-1.0-2.4.3-ml5.tar.gz             subversion-locale-ko-1.3.1-r1.tar.gz
libreadline-dbg-4.3-r3.tar.gz                 subversion-locale-nb-1.3.1-r1.tar.gz
libreadline-dev-4.3-r3.tar.gz                 subversion-locale-pl-1.3.1-r1.tar.gz
libreadline-doc-4.3-r3.tar.gz                 subversion-locale-pt-br-1.3.1-r1.tar.gz
libreadline4-4.3-r3.tar.gz                    subversion-locale-sv-1.3.1-r1.tar.gz
libsm-dbg-X11R7.1-1.0.1-r0.tar.gz             subversion-locale-zh-cn-1.3.1-r1.tar.gz
libsm-dev-X11R7.1-1.0.1-r0.tar.gz             subversion-locale-zh-tw-1.3.1-r1.tar.gz
libsm6-X11R7.1-1.0.1-r0.tar.gz                tcl-8.4.11-r3.tar.gz
libsqlite-bin-2.8.17-r2.tar.gz                tcl-dbg-8.4.11-r3.tar.gz
libsqlite-dbg-2.8.17-r2.tar.gz                tcl-dev-8.4.11-r3.tar.gz
libsqlite-dev-2.8.17-r2.tar.gz                tcl-doc-8.4.11-r3.tar.gz
libsqlite0-2.8.17-r2.tar.gz                   time-1.7-r0.tar.gz
libsqlite3-0-3.3.7-r2.tar.gz                  time-dbg-1.7-r0.tar.gz
libsqlite3-dev-3.3.7-r2.tar.gz                time-doc-1.7-r0.tar.gz
libssl0.9.7-0.9.7g-r1.tar.gz                  tmp
libx11-6-X11R7.1-1.0.1-r1.tar.gz              update-rc.d-0.7-r0.tar.gz
libx11-dbg-X11R7.1-1.0.1-r1.tar.gz            util-macros-dev-X11R7.1-1.0.2-r0.tar.gz
libx11-dev-X11R7.1-1.0.1-r1.tar.gz            vim-7.0-r0.tar.gz
libx11-doc-X11R7.1-1.0.1-r1.tar.gz            vim-doc-7.0-r0.tar.gz
libx11-locale-X11R7.1-1.0.1-r1.tar.gz         vim-help-7.0-r0.tar.gz
libxau-dbg-X11R7.1-1.0.1-r0.tar.gz            vim-syntax-7.0-r0.tar.gz
libxau-dev-X11R7.1-1.0.1-r0.tar.gz            vim-tutor-7.0-r0.tar.gz
libxau-doc-X11R7.1-1.0.1-r0.tar.gz            wget-1.9.1-r6.tar.gz
libxau6-X11R7.1-1.0.1-r0.tar.gz               wget-dbg-1.9.1-r6.tar.gz
libxdmcp-dbg-X11R7.1-1.0.1-r0.tar.gz          wget-doc-1.9.1-r6.tar.gz
libxdmcp-dev-X11R7.1-1.0.1-r0.tar.gz          wget-locale-bg-1.9.1-r6.tar.gz
libxdmcp6-X11R7.1-1.0.1-r0.tar.gz             wget-locale-ca-1.9.1-r6.tar.gz
libxml2-2.6.22-r3.tar.gz                      wget-locale-cs-1.9.1-r6.tar.gz
libxml2-dbg-2.6.22-r3.tar.gz                  wget-locale-da-1.9.1-r6.tar.gz
libxml2-dev-2.6.22-r3.tar.gz                  wget-locale-de-1.9.1-r6.tar.gz
libxml2-doc-2.6.22-r3.tar.gz                  wget-locale-el-1.9.1-r6.tar.gz
libxml2-utils-2.6.22-r3.tar.gz                wget-locale-es-1.9.1-r6.tar.gz
libxt-dbg-X11R7.1-1.0.2-r0.tar.gz             wget-locale-et-1.9.1-r6.tar.gz
libxt-dev-X11R7.1-1.0.2-r0.tar.gz             wget-locale-fr-1.9.1-r6.tar.gz
libxt-doc-X11R7.1-1.0.2-r0.tar.gz             wget-locale-gl-1.9.1-r6.tar.gz
libxt6-X11R7.1-1.0.2-r0.tar.gz                wget-locale-he-1.9.1-r6.tar.gz
libz-dbg-1.2.3-r1.tar.gz                      wget-locale-hr-1.9.1-r6.tar.gz
libz-dev-1.2.3-r1.tar.gz                      wget-locale-hu-1.9.1-r6.tar.gz
libz1-1.2.3-r1.tar.gz                         wget-locale-it-1.9.1-r6.tar.gz
minicom-2.1-r0.tar.gz                         wget-locale-ja-1.9.1-r6.tar.gz
minicom-dbg-2.1-r0.tar.gz                     wget-locale-nl-1.9.1-r6.tar.gz
minicom-doc-2.1-r0.tar.gz                     wget-locale-no-1.9.1-r6.tar.gz
ncurses-5.4-r8.tar.gz                         wget-locale-pl-1.9.1-r6.tar.gz
ncurses-dbg-5.4-r8.tar.gz                     wget-locale-pt-br-1.9.1-r6.tar.gz
ncurses-dev-5.4-r8.tar.gz                     wget-locale-ro-1.9.1-r6.tar.gz
ncurses-doc-5.4-r8.tar.gz                     wget-locale-ru-1.9.1-r6.tar.gz
ncurses-terminfo-5.4-r8.tar.gz                wget-locale-sk-1.9.1-r6.tar.gz
ncurses-tools-5.4-r8.tar.gz                   wget-locale-sl-1.9.1-r6.tar.gz
openssl-0.9.7g-r1.tar.gz                      wget-locale-sv-1.9.1-r6.tar.gz
openssl-dbg-0.9.7g-r1.tar.gz                  wget-locale-tr-1.9.1-r6.tar.gz
openssl-dev-0.9.7g-r1.tar.gz                  wget-locale-uk-1.9.1-r6.tar.gz
openssl-doc-0.9.7g-r1.tar.gz                  wget-locale-zh-cn-1.9.1-r6.tar.gz
python-audio-2.4.3-ml0.tar.gz                 wget-locale-zh-tw-1.9.1-r6.tar.gz
python-bsddb-2.4.3-ml0.tar.gz                 xcmiscproto-dev-X11R7.0-1.1.2-r0.tar.gz
python-codecs-2.4.3-ml0.tar.gz                xextproto-dev-X11R7.0-7.0.2-r0.tar.gz
python-compile-2.4.3-ml0.tar.gz               xf86bigfontproto-dev-X11R7.0-1.1.2-r0.tar.gz
python-compiler-2.4.3-ml0.tar.gz              xproto-dev-X11R7.1-7.0.5-r0.tar.gz
python-compression-2.4.3-ml0.tar.gz           xtrans-dev-X11R7.0-1.0.0-r1.tar.gz
python-core-2.4.3-ml1.tar.gz
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Installing the needed packages is just a matter of uncompressing a subset of the above files on the target system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This exercise demonstrates how a developer can quickly (took me less than 4 hours) add a large number of applications (and dependencies) to about any Embedded Linux system.  Leveraging embedded Linux is being able to use the components &lt;em&gt;&lt;strong&gt;you&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; need.  Please contact us if you would like additional details or assistance.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Moxa UC7408 Review</title>
        <published>2006-09-29T00:00:00+00:00</published>
        <updated>2006-09-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/124/moxa-uc7408-review/"/>
        <id>https://bec-systems.com/124/moxa-uc7408-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/124/moxa-uc7408-review/">&lt;p&gt;I am currently evaluating a Moxa UC7408 for one of my customers.  The UC7408 is a small fanless industrial computer that runs Linux or Windows CE.  This article provides a basic overview of this unit and a review of some of the UC7408 features and the Linux distribution Moxa provides.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_1-1.jpg&quot; alt=&quot;moxa_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The basic specifications for the UC7408 are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;relatively small size and fanless&lt;&#x2F;li&gt;
&lt;li&gt;Intel Xscale IXP-422 266MHz Processor&lt;&#x2F;li&gt;
&lt;li&gt;8 RS232&#x2F;422&#x2F;485 serial ports&lt;&#x2F;li&gt;
&lt;li&gt;8 digital Input and 8 digital output ports&lt;&#x2F;li&gt;
&lt;li&gt;dual 10&#x2F;100 Ethernet&lt;&#x2F;li&gt;
&lt;li&gt;PCMCIA, CompactFlash, Wireless LAN Expansion (supports 802.11b&#x2F;802.11g)&lt;&#x2F;li&gt;
&lt;li&gt;Runs Linux or WinCE&lt;&#x2F;li&gt;
&lt;li&gt;Console serial port&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;documentation&quot;&gt;Documentation&lt;&#x2F;h3&gt;
&lt;p&gt;The documentation Moxa provides is adequate and fairly detailed.  The moxa documents include a quick install guide, hardware user’s manual, and a 114 page user’s manual.  As good as this documentation is, a general knowledge of Linux is always helpful when working with embedded Linux systems.  Basics like using SSH, FTP, Telnet, and basic Linux system administration are essential when working with embedded Linux.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-distribution&quot;&gt;Linux Distribution&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux Distribution provided by Moxa is fairly full featured.  A few highlights with the v1.8 Linux firmware:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provides a 26MB user JFFS2 flash partition.  This partition is read&#x2F;write and is about 45% full leaving about 14.5MB for user files.  It is probably also possible to delete some of the files that are not required, freeing up more space.&lt;&#x2F;li&gt;
&lt;li&gt;Apache &amp;amp; PHP support&lt;&#x2F;li&gt;
&lt;li&gt;SSH&lt;&#x2F;li&gt;
&lt;li&gt;a number of other utilities are provided such as telnet, ftp, iptables, etc.&lt;&#x2F;li&gt;
&lt;li&gt;VI editor&lt;&#x2F;li&gt;
&lt;li&gt;Many command line utilities found in most Linux systems.&lt;&#x2F;li&gt;
&lt;li&gt;2.4.18 Kernel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Linux distribution seems to be based on MontaVista Linux and seems fairly solid.  I ran through some of the basics like mounting a CF card and everything seems to work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;firmware-updates-and-recovery-mode&quot;&gt;Firmware Updates and Recovery Mode&lt;&#x2F;h3&gt;
&lt;p&gt;Moxa provides a mechanism to update the firmware in the system.  This update is a global flash update that programs the entire flash and will erase all user changes.  The update works by enabling a RAM file system and copying the new flash image to the ram file system.  Running an update command that copies the firmware update file into flash.&lt;&#x2F;p&gt;
&lt;p&gt;The 7408 contains a stripped down version of Linux in a separate flash partition that can be booted in a recovery mode if the User flash partition becomes corrupted or unusable.  This mode can be enabled by pressing the “Reset to Default” button on the unit and powering it on.  In this mode, there is no ssh support and you must ftp an image from an ftp server to the device and then reflash it.  This requires you to set up an ftp server that the Moxa system can access.  While this is an entirely workable solution, it may be a challenge for inexperienced Linux users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tools&quot;&gt;Tools&lt;&#x2F;h3&gt;
&lt;p&gt;Moxa provides a Linux and Windows toolchain to use with the device.  I have built a number of packages with the Linux toolchain and it seems to work well.  It is based on GCC 3.3.2.  Cross compiling applications for embedded Linux is always a challenge and in a future article I will present a way to use OpenEmbedded to compile a number of packages using the Moxa toolchain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;possible-improvements&quot;&gt;Possible Improvements&lt;&#x2F;h3&gt;
&lt;p&gt;There would be some benefits if the system was a little more open in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;access to the bootloader console and documentation.  This would allow developers to more easily flash their own software.&lt;&#x2F;li&gt;
&lt;li&gt;readily provide source for GPL components.  Moxa provides a form that you can fill out to receive GPL source code on a CE.  The cost is $100.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One of the big advantages of using Linux in an embedded system is the ability to use the many open source components available.  The easier an embedded solution provider makes this for developers, the more value their system provides.  See the white paper &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;Tips for Planning Your Embedded Linux Project&lt;&#x2F;a&gt; (&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;) for more ideas on this subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Overall, the Moxa system seems very usable and the hardware is quite nice.  Stay tuned for future articles about how to get the most out of this system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_2-1.jpg&quot; alt=&quot;moxa_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_3-1.jpg&quot; alt=&quot;moxa_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_4-1.jpg&quot; alt=&quot;moxa_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to evaluate VoIP providers with Asterisk</title>
        <published>2006-09-20T00:00:00+00:00</published>
        <updated>2006-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/269/how-to-evaluate-voip-providers-with-asterisk/"/>
        <id>https://bec-systems.com/269/how-to-evaluate-voip-providers-with-asterisk/</id>
        
        <content type="html" xml:base="https://bec-systems.com/269/how-to-evaluate-voip-providers-with-asterisk/">&lt;p&gt;There are many options when selecting a VoIP provider to terminate your Asterisk PBX.  One of the most important factors in this selection is the quality of the internet connection between your PBX and the VoIP provider.  The route between you and your VoIP provider is one of the most important considerations when selecting a provider.  This article details a simple method for evaluating this connection using Asterisk.&lt;&#x2F;p&gt;
&lt;p&gt;Asterisk includes a feature that can be used to monitor the latency between your system and a &lt;em&gt;peer&lt;&#x2F;em&gt; or &lt;em&gt;friend&lt;&#x2F;em&gt;.  This feature is enabled by setting the &lt;em&gt;qualify&lt;&#x2F;em&gt; setting in the &lt;em&gt;iax.conf&lt;&#x2F;em&gt; configuration file.  Valid options are &lt;em&gt;yes&lt;&#x2F;em&gt;, &lt;em&gt;no&lt;&#x2F;em&gt;, or a time in milliseconds.  If qualify is enabled, NOTIFY messages are sent periodically to the peer and the latency between replies is measured.  The peer is determined unreachable if the number of milliseconds is greater than the qualify value or 2,000 if qualify  is set to &lt;em&gt;yes&lt;&#x2F;em&gt;.  If a peer is unreachable, events are logged in &#x2F;var&#x2F;log&#x2F;asterisk&#x2F;messages as shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Sep 19 21:48:19 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now UNREACHABLE! Time: 49
Sep 19 21:50:09 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now REACHABLE! Time: 49
Sep 20 07:16:38 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now TOO LAGGED (769 ms)!
Sep 20 07:16:48 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now REACHABLE! Time: 50
Sep 20 12:09:31 NOTICE[752] chan_iax2.c: Peer &amp;#39;teliax&amp;#39; is now TOO LAGGED (2923 ms)!
Sep 20 12:17:27 NOTICE[752] chan_iax2.c: Peer &amp;#39;teliax&amp;#39; is now REACHABLE! Time: 83
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am currently using two different VoIP providers and I get qualify notice messages about once every day or two with the qualify set to 400ms.  This is a very useful information as it allows me to determine which provider has the most reliable route from my office.  If you get very few qualify NOTICE messages, you can probably assume your VoIP connection will be fairly reliable.&lt;&#x2F;p&gt;
&lt;p&gt;Have connections with two different providers also tells me when the congestion is with my Internet connection or if it is something beyond my connection.  If both providers go out at the same time, it is most likely the internet connection at my office or problems with my ISP.  I rarely if ever see this scenario, so I can conclude that my internet connection is fairly reliable and the congestion problems are most likely between me and the VoIP provider or problems at the VoIP provider.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, things are now working fairly well.  As we continue to resolve problems, VoIP is now starting to become a very usable option for us.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Implenting QoS for VOIP in a Linksys router</title>
        <published>2006-08-28T00:00:00+00:00</published>
        <updated>2006-08-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/264/implenting-qos-for-voip-in-a-linksys-router/"/>
        <id>https://bec-systems.com/264/implenting-qos-for-voip-in-a-linksys-router/</id>
        
        <content type="html" xml:base="https://bec-systems.com/264/implenting-qos-for-voip-in-a-linksys-router/">&lt;p&gt;In our quest to implement an Asterisk PBX in our office, we are evaluating several VOIP (Voice Over IP) providers.  VOIP provides several benefits over traditional phone lines including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;low cost (typically around $0.02 per minute)&lt;&#x2F;li&gt;
&lt;li&gt;available in pre-paid plans&lt;&#x2F;li&gt;
&lt;li&gt;can support concurrent concurrent calls on the same number&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;However, implementing VOIP successfully is not trivial.  You &lt;strong&gt;must&lt;&#x2F;strong&gt; have a reliable internet connection and we have found you must implement some type of Quality of Service (QoS) in the router. The first problem I ran into was calls sounded great to me, but people I called mentioned the calls sometimes sounded garbled to them.  This article discusses the diagnosis of this problem and how to implement QoS in a Linksys router to fix this issue.&lt;&#x2F;p&gt;
&lt;p&gt;Our connection is a standard DSL connection – 5Mb&#x2F;sec down and 640Kb&#x2F;sec up.  There is plenty of bandwidth for incoming voice, but bandwidth for outgoing voice is much more limited.  A few tests confirmed this – when a ftp upload or some other bulk transfer was occurring, the outgoing voice sounded really bad.&lt;&#x2F;p&gt;
&lt;p&gt;The solution to this problem is to implement some type of Quality of Service (QoS) mechanism that prioritizes the VOIP traffic over all other types of traffic.  Vonage and other “boxed” solutions no doubt do this as they recommend placing their box between the modem and the router. It turns out that QoS can be implemented in a standard Linksys router&#x2F;firewall.  I spent some time trying to get QoS working using a Linksys WRT54G v5 router with no success, I ended up loading the dd-wrt firmware (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.dd-wrt.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.dd-wrt.com&lt;&#x2F;a&gt;) on an older Linksys router I had laying around.  The dd-wrt firmware is quite nice and is worthy of consideration if you have a v4 or earlier Linksys router or the WRT54GL version.   QoS may have worked on the WRT54G v5 with Linksys firmware with some more effort, but after trying dd-wrt, I’m not going back.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-qos&quot;&gt;Setting up QOS&lt;&#x2F;h2&gt;
&lt;p&gt;The QoS settings can be found under Applications &amp;amp; Gaming -&amp;gt; QoS.&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways to assign priority to your VOIP system.  I just used the IP address as shown below.  192.168.1.10 is the LAN private IP of the Asterisk system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;qos1-1.png&quot; alt=&quot;qos1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With the priority of the Asterisk box set to high, we should be all set.  It turns out that unless you cap the bandwidth, you will still have QoS problems.  Enter around 85% of your up and down bandwidth in the Uplink and Downlink boxes.  Capping the bandwidth is required to keep the latency low.  Otherwise, your bandwidth is filled up with large packets and the priority settings are not effective for VOIP traffic.  See &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.dd-wrt.com&#x2F;wiki&#x2F;index.php&#x2F;Quality_of_Service&quot;&gt;http:&#x2F;&#x2F;www.dd-wrt.com&#x2F;wiki&#x2F;index.php&#x2F;Quality_of_Service&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;qos2-1.png&quot; alt=&quot;qos2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With the above settings, VOIP calls are now clear even with other concurrent activities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Several people have reported being able to install dd-wrt on v6 WRT54 routers and the QoS configuration is the same.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded is a Service Industry</title>
        <published>2006-06-02T00:00:00+00:00</published>
        <updated>2006-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/60/embedded-is-a-service-industry/"/>
        <id>https://bec-systems.com/60/embedded-is-a-service-industry/</id>
        
        <content type="html" xml:base="https://bec-systems.com/60/embedded-is-a-service-industry/">&lt;p&gt;Linuxdevices.com has recently published an article titled: &lt;em&gt;Let’s call Embedded what it is – a Service Industry&lt;&#x2F;em&gt;(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxdevices.com&#x2F;articles&#x2F;AT6989225710.html&quot;&gt;http:&#x2F;&#x2F;linuxdevices.com&#x2F;articles&#x2F;AT6989225710.html&lt;&#x2F;a&gt;).  In this article, Curt Schacker discusses how little growth there has been in the Embedded Systems industry. He claims that most embedded companies are trying to establish themselves as product companies, when the market is really a services market.  Having worked for two Embedded companies in the past that went out of business, I think he is right.  I have often heard the argument that service companies are too much work, they don’t scale, etc.  But, to me services has always been a more natural fit for myself and an embedded systems company – one of the reasons BEC Systems exists.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>TRAC and Distributed Development</title>
        <published>2006-05-29T00:00:00+00:00</published>
        <updated>2006-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/231/trac-and-distributed-development/"/>
        <id>https://bec-systems.com/231/trac-and-distributed-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/231/trac-and-distributed-development/">&lt;p&gt;I have long been a big fan of source control tools and issue tracking systems.  The “concurrent” model made popular by CVS is a tremendous benefit any time there are multiple people working on the same project.  For most of the projects BEC participates in, we end up setting up a source control system (usually Subversion these days) and an issue tracking system (typically Bugzilla).  On one of my recent projects, I decided to try the trac integrated SCM &amp;amp; Project Management tool.  Trac brings together several functions into a clean, easy to use web based tool for managing projects.  This article relates some of my experiences and the benefits of using trac.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-trac&quot;&gt;What is trac?&lt;&#x2F;h2&gt;
&lt;p&gt;Trac provides the following functions (from the trac website - &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.edgewall.com&#x2F;trac&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.edgewall.com&#x2F;trac&#x2F;&lt;&#x2F;a&gt; ):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An integrated system for managing software projects&lt;&#x2F;li&gt;
&lt;li&gt;An enhanced wiki&lt;&#x2F;li&gt;
&lt;li&gt;A flexible web-based issue tracker&lt;&#x2F;li&gt;
&lt;li&gt;An interface to the Subversion revision control system&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;why-is-trac-so-interesting&quot;&gt;Why is trac so interesting?&lt;&#x2F;h2&gt;
&lt;p&gt;Although all of these functions are available as separate tools, having them in one tool has several benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The tool is more likely to be used if everything is in one place&lt;&#x2F;li&gt;
&lt;li&gt;The ease of cross referencing wiki pages, issues, and Subversion changesets compounds the usefulness of each tool.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I have been using and implementing collaboration tools for years and one thing you eventually learn is that getting people to use collaboration tools is a big challenge (see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.linux-watch.com&#x2F;news&#x2F;NS9450464356.html&quot;&gt;http:&#x2F;&#x2F;www.linux-watch.com&#x2F;news&#x2F;NS9450464356.html&lt;&#x2F;a&gt; for some more thoughts on this subject).  Having mutiple tools in one place greatly increases the likelihood they will be used.  A typical session might go something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A developer might want to see what has changed recently in the code base, so he logs into trac to view the timeline – after all, most developers are mainly concerned with code.&lt;&#x2F;li&gt;
&lt;li&gt;As the trac timeline lists all changes (wiki and issues as well as source code changes), he notices that a wiki page with notes about driver X has changed – that looks interesting, so he view the page.  While viewing the page, the developer notes there is some missing information, so he adds the information by simply editing the page.&lt;&#x2F;li&gt;
&lt;li&gt;Once this habit is established, it can greatly improve the productivity of the team as the project becomes more transparent to all team members.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Any collaboration tool must be easy to use and provide an obvious benefit to those using the tool.&lt;&#x2F;p&gt;
&lt;p&gt;The wiki markup used in trac is used for both wiki pages as well as issue&#x2F;bug reports.  Referencing an issue in a wiki page or another bug report is simple as typing #&lt;issue number&gt;.  It is also very easy to reference code changsets in the wiki markup by simply typing r&lt;change set number&gt; (see image below).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;trac3-1.png&quot; alt=&quot;trac3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Clicking on a issue or changeset  number will take you directly to the information.  The trac interface is very clean and very easy to use.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distributed-teams&quot;&gt;Distributed teams&lt;&#x2F;h2&gt;
&lt;p&gt;Tools like trac allow for very effective distributed teams.  The success of Open Source software has proven that development can occur efficiently in a distributed manner.  BEC has integrated this model and we regularly work with people all over the country and in Europe.  When there is a process for all people involved in the project to keep up with its status and progress, distributed development becomes very possible.  Often, the customer is part of the development team.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;project-transparency&quot;&gt;Project Transparency&lt;&#x2F;h2&gt;
&lt;p&gt;Another benefit of trac for BEC, is that we can easily provide project transparency to our customers.   It is BEC’s practice to provide customers with access to the project as it develops, so we give our customers trac logins and they can follow the progress by watching the timeline and milestone pages.  This gives the customer an assurance that progress is being made on the project and some insight into some of the issues encountered.  Having a comprehensive view into the project also allows customers to provide early feedback and reduces BEC’s project management and reporting overhead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Tools like trac improve our customer relationships, increase efficiency and reduce our costs.  If you are interested in implementing tools like trac, BEC can assist you in selecting and implementing the right tools to make your projects run smoothly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Opencores SPI Controller Review</title>
        <published>2006-05-08T00:00:00+00:00</published>
        <updated>2006-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/66/opencores-spi-controller-review/"/>
        <id>https://bec-systems.com/66/opencores-spi-controller-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/66/opencores-spi-controller-review/">&lt;p&gt;Recently, I had the opportunity to use a SPI controller from Opencores in a customer design based on an Intel PXA255 processor and a Xilinx CPLD.  The customer did not want to change the processor or the CPLD family, but needed an extra SPI interface in the device.  I had my doubts, but mentioned I would look into a SPI controller from Opencores.  To my surprise, the core fit in a Xilinx CPLD and worked out very well.  We have since upgraded to a Altera MAXII CPLD.  This review details this effort.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;spi-controller-overview&quot;&gt;SPI Controller Overview&lt;&#x2F;h3&gt;
&lt;p&gt;The SPI controller is based on the interface for a standard Motorolla SPI controller and is available at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.opencores.org&#x2F;projects.cgi&#x2F;web&#x2F;spi&#x2F;overview&quot;&gt;http:&#x2F;&#x2F;www.opencores.org&#x2F;projects.cgi&#x2F;web&#x2F;spi&#x2F;overview&lt;&#x2F;a&gt; .  The core includes the following features:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Full duplex synchronous serial data transfer&lt;&#x2F;li&gt;
&lt;li&gt;Variable length of transfer word up to 128 bits&lt;&#x2F;li&gt;
&lt;li&gt;MSB or LSB first data transfer&lt;&#x2F;li&gt;
&lt;li&gt;Rx and Tx on both rising or falling edge of serial clock independently&lt;&#x2F;li&gt;
&lt;li&gt;8 slave select lines&lt;&#x2F;li&gt;
&lt;li&gt;Fully static synchronous design with one clock domain&lt;&#x2F;li&gt;
&lt;li&gt;Technology independent Verilog&lt;&#x2F;li&gt;
&lt;li&gt;Fully synthesizable&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A datasheet type document is provided with the core that provides the necessary information for developers writing software for this core.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-wishbone-bus&quot;&gt;The Wishbone bus&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the cores from Opencores uses the Wishbone bus standard.  The Wishbone bus is a synchronous bus designed to be used inside an IC.  The CPLD was connected to the PXA255 processors asynchrous bus, so most of the effort required was to create an PXA255 &amp;lt;-&amp;gt; Wishbone interface module.  At some point, I hope to release this module on Opencores.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;simulation&quot;&gt;Simulation&lt;&#x2F;h3&gt;
&lt;p&gt;The simulation was done using the Icarus Verilog simulator under Linux.  Below is a screen shot of the simulation displayed in GTKWave:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;spi_sim_small-1.png&quot; alt=&quot;spi_sim_small&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h3&gt;
&lt;p&gt;The Opencores SPI core worked out very well in our design and I was very impressed with quality of this core.  The documentation is more than adequate.  Standards like Verilog make it very easy to move designs between different vendors devices and allows designers to use tools of their choice such as the Icarus Verilog simulator.  As FPGAs and CPLDs become more larger and more standand, Opencores is valuable resource for adding standard interfaces to these devices.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Really Nice Hex Calculator</title>
        <published>2006-05-02T00:00:00+00:00</published>
        <updated>2006-05-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/226/a-really-nice-hex-calculator/"/>
        <id>https://bec-systems.com/226/a-really-nice-hex-calculator/</id>
        
        <content type="html" xml:base="https://bec-systems.com/226/a-really-nice-hex-calculator/">&lt;p&gt;When working with embedded software, I often have a need for a hex calculator.  Over the years I’ve used a number of different tools.  Through college and for several years after, I used my HP48 calculator.  It is a great tool.  Around 1998, I discovered the Python programming language.  As Python supports an interactive session, it works well as a desktop calculator – I don’t think I have used my HP48 since I discovered Python.  Recently, I’ve been using Ruby more in place of Python and am finding it is even nicer.  This article presents several tips and snippets of code for using Ruby as a very effective hex calculator.&lt;&#x2F;p&gt;
&lt;p&gt;For those of you not familiar with Ruby, Ruby is an interpreted scripting language for quick and easy object-oriented programming – similar in concept to Python or Perl.&lt;&#x2F;p&gt;
&lt;p&gt;Ruby provides an interactive Ruby shell called “irb”.  After you install Ruby, you can run irb from a command prompt.  You can immediately do useful calculations like the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):001:0&amp;gt; a = 10
=&amp;gt; 10
irb(main):002:0&amp;gt; b = 23
=&amp;gt; 23
irb(main):003:0&amp;gt; a+b
=&amp;gt; 33
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hexadecimal numbers are prefixed with “0x” as in many other languages:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):005:0&amp;gt; c = 0x1000
=&amp;gt; 4096
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is easy to convert from hex to decimal – just type the hex number, hit return and Ruby will give you the decimal equivalent as shown above.   To convert from decimal to hex, I often just use the &lt;em&gt;printf&lt;&#x2F;em&gt; statement.  The syntax is similar to C, so it is very natural for embedded programmers.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):006:0&amp;gt; printf &amp;quot;0x%x&amp;quot;, (3*1024*1024)
0x300000=&amp;gt; nil
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ruby provides standard shift operators similar to those found in C.  For example, if you want to know the hex value when bits 15 and 23 are set high:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):019:0&amp;gt; printf &amp;quot;0x%x&amp;quot;, (1&amp;lt;&amp;lt;15)|(1&amp;lt;&amp;lt;23)
0x808000=&amp;gt; nil
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is often useful to know what bits are set in a particular number when determining if a bit in a status register is high, what address bits are used, etc. Ruby provides a bit reference method in the form.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;fix[n]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;n is the nth bit in a binary number &lt;em&gt;fix&lt;&#x2F;em&gt; where fix[0] is the least significant bit.  Some examples:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):010:0&amp;gt; 2[0]
=&amp;gt; 0
irb(main):011:0&amp;gt; 2[1]
=&amp;gt; 1
 irb(main):017:0&amp;gt; a = 3*1024*1024
=&amp;gt; 3145728
irb(main):018:0&amp;gt; 31.downto(0) {|n| print a[n]}
00000000001100000000000000000000=&amp;gt; 31
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For convenience, I wrote a simple module called &lt;em&gt;bits.rb&lt;&#x2F;em&gt; that extends the basic Integer number class and provides a nice display of the bits in a number.  To use this, create a file called bits.rb with the following contents and drop it in your Ruby &lt;em&gt;site_ruby&lt;&#x2F;em&gt; directory.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; M = 1024*1024
K = 1024

class Integer
        def bits
                print &amp;quot;3322222222221111111111n&amp;quot;
                print &amp;quot;10987654321098765432109876543210n&amp;quot;
                print &amp;quot;---|---|---|---|---|---|---|---|n&amp;quot;
                31.downto(0) { |x| print self[x] }
        end
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And to use this extension to see what address bits are used to decode 8MB of address space:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):020:0&amp;gt; require &amp;#39;bits&amp;#39;
=&amp;gt; true
irb(main):021:0&amp;gt; (8*M).bits
3322222222221111111111
10987654321098765432109876543210
---|---|---|---|---|---|---|---|
00000000100000000000000000000000=&amp;gt; 31
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From this example, we can see that address bits 0 through 23 are required to decode 8MB of address space.&lt;&#x2F;p&gt;
&lt;p&gt;===========================================&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2009-07-30&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The following was posted as a comment to my old web site:&lt;&#x2F;p&gt;
&lt;p&gt;An even easier way of converting between bases in Ruby:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):001:0&amp;gt; puts 300.to_s(16)
12c
=&amp;gt; nil
irb(main):002:0&amp;gt; puts &amp;quot;12c&amp;quot;.to_i(16)
300
=&amp;gt; nil
irb(main):003:0&amp;gt; puts 255.to_s(2)
11111111
=&amp;gt; nil
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very nice!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Specialization or not</title>
        <published>2005-11-15T00:00:00+00:00</published>
        <updated>2005-11-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/55/specialization-or-not/"/>
        <id>https://bec-systems.com/55/specialization-or-not/</id>
        
        <content type="html" xml:base="https://bec-systems.com/55/specialization-or-not/">&lt;p&gt;I have often wondered about specialization.  We can often find ourselves in ruts if we specialize too much.  But on the other hand, specialization can lead efficiencies in some cases.  In my work as a consultant, I often find myself in new situations where I have to learn fast.  As one of my associates states – problem solving is the key skill.  Kevin Barnes article &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.journalhome.com&#x2F;codecraft&#x2F;15583&#x2F;&quot;&gt;Three theories on how to use developers efficiently&lt;&#x2F;a&gt; is a good read about the subject.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Total Phase USB Protocol Analyzer review</title>
        <published>2005-11-03T00:00:00+00:00</published>
        <updated>2005-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/222/total-phase-usb-protocol-analyzer-review/"/>
        <id>https://bec-systems.com/222/total-phase-usb-protocol-analyzer-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/222/total-phase-usb-protocol-analyzer-review/">&lt;p&gt;I recently purchased a USB protocol analyzer from &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.totalphase.com&#x2F;products&#x2F;beagle&#x2F;usb&#x2F;&quot;&gt;Total Phase&lt;&#x2F;a&gt;.  The device will analyze full speed USB traffic and works well with Linux.  On Linux, the software makes use of libusb, so there is very little setup required to get the device working – very nice.  At a price of $400, there is really no reason not to have one if you are doing any type of USB development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;beagle-1.jpg&quot; alt=&quot;beagle&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Economics and Finding Outsourcing Talent</title>
        <published>2005-11-03T00:00:00+00:00</published>
        <updated>2005-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/51/economics-and-finding-outsourcing-talent/"/>
        <id>https://bec-systems.com/51/economics-and-finding-outsourcing-talent/</id>
        
        <content type="html" xml:base="https://bec-systems.com/51/economics-and-finding-outsourcing-talent/">&lt;p&gt;Economics In One Lesson by Henry Hazlitt presents an interesting and logical view of economics.  The book presents many ideas that seem right (like saving) and provides very logical arguments to back them up.  Even though the book was originally published in 1946, the topics covered seem very applicable to today (The Blessings of Destruction, Public Works Mean Taxes, Taxes Discourage Production, Credit Diverts Production, The Curse of Machinery, Spread-the-Work Schemes, Disbanding Troops and Bureaucrats, The Fetish of Full Employment, Who’s “Protected” by Tariffs?, The Drive for Exports, “Parity” Prices, Saving the X Industry, How the Price System Works, “Stabilizing” Commodities, Government Price-Fixing, What Rent Control Does, Minimum Wage Laws, Do Unions Really Raise Wages?, “Enough to Buy Back the Product”, The Function of Profits, The Mirage of Inflation, The Assault on Saving)&lt;&#x2F;p&gt;
&lt;p&gt;The book can be found:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;online: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;jim.com&#x2F;econ&#x2F;contents.html&quot;&gt;http:&#x2F;&#x2F;jim.com&#x2F;econ&#x2F;contents.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;download: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.fee.org&#x2F;pdf&#x2F;books&#x2F;Economics_in_one_lesson.pdf&quot;&gt;http:&#x2F;&#x2F;www.fee.org&#x2F;pdf&#x2F;books&#x2F;Economics_in_one_lesson.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;amazon.com&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following article presents some of the realities of finding talent in places like India.  It is encouraging that the basic economic laws of supply and demand still work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;finding-coders-on-the-subcontinent&quot;&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.journalhome.com&#x2F;codecraft&#x2F;13920&#x2F;&quot;&gt;Finding coders on the subcontinent&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
</content>
        
    </entry>
</feed>
